summaryrefslogtreecommitdiff
path: root/libjava/java
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@gcc.gnu.org>2004-11-30 23:59:12 +0000
committerGraydon Hoare <graydon@gcc.gnu.org>2004-11-30 23:59:12 +0000
commitea28b8f60fb4113053238a22a4d2c508f39710bb (patch)
tree35ad0bbb429ac9e5e658fea57b904ce331b0a4dd /libjava/java
parentc21accc5d9378aa5b20c868364d8025faa5b1ea5 (diff)
downloadgcc-ea28b8f60fb4113053238a22a4d2c508f39710bb.tar.gz
revert: [multiple changes]
2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * gnu/java/awt/peer/gtk/GdkGraphics.java (drawImage variants): Update image observer. * gnu/java/awt/peer/gtk/GtkComponentPeer.java (createImage): Start image production. * gnu/java/awt/peer/gtk/GtkFramePeer.java (setMenuBar): Protect against negative menu bar widths. (setBounds): Likewise. (postConfigureEvent): Likewise. * gnu/java/awt/peer/gtk/GtkImage.java (imageComplete): Don't remove consumer unless only a single frame has completed. * gnu/java/awt/peer/gtk/GtkImagePainter.java (GtkImagePainter): Add observer parameter. (setPixels): Update image observer. (imageComplete): Likewise. * java/applet/Applet.java (width): New field. (height): Likewise. (setStub): Set size if width or height field has been set. (resize): If stub is null save width and height values. * java/awt/Component.java (reshape): Protect against null parent. * java/awt/image/MemoryImageSource.java (MemoryImageSource(int,int,ColorModel,byte[],int,int)): Document. (MemoryImageSource(int,int,ColorModel,int[],int,int)): Likewise. (MemoryImageSource(int,int,ColorModel,byte[],int,int,Hashtable)): Reference pixel array directly, rather than creating a local copy. (MemoryImageSource(int,int,ColorModel,int[],int,int,Hashtable)): Likewise. (newPixels(int,int,int,int)): Fix for loop and array copy bounds. (newPixels(int,int,int,int,boolean)): Likewise. (startProduction): If animated call imageComplete with SINGLEFRAME. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c: Uncomment gdk_flush lines. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c (drawPixels): Return if g is null or g->drawable is not a gdk drawable. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/DefaultSingleSelectionModel.java, javax/swing/JPasswordField.java, javax/swing/tree/AbstractLayoutCache.java: Reformatted and javadocs cleaned up. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/Component.java: Fixed argument names to match javadocs. (setFont): Rewritten set property first and then fire event. (setLocale): Likewise. * javax/swing/text/JTextComponent.java (setEditable): Likewise. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/Button.java (AccessibleAWTButton.getAccessibleActionDescription): Explain the source of 'click'. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/Checkbox.java: Remove stub comments. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/Button.java (AccessibleAWTButton.getAccessibleActionDescription): Return 'click'. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/CardLayout.java: Made some constants static. (serialVersionUID): Made private. (addLayoutComponent): Simplified code. * java/awt/event/InputEvent.java (getModifiersEx): Added missing @param tag. * java/awt/image/RGBImageFilter.java (filterRGBPixels): Reformatted, removed wrong @param tag. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/text/FieldView.java, javax/swing/text/JTextComponent.java: Removed debug code. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/BorderFactory.java (BorderFactory): Added private constructor. * javax/swing/SwingUtilities.java (SwingUtilities): Likewise. (computeStringWidth): New method. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/color/ICC_Profile.java (icSigNamedColorTag): Removed. * java/awt/datatransfer/DataFlavor.java (isMimeTypeEqual): Made final. * java/awt/image/AffineTransformOp.java: Reworked javadocs. (TYPE_BICUBIC): Added @since tag. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/Checkbox.java (AccessibleAWTCheckBox): Remove todo comments. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/Checkbox.java (itemStateChanged): Implement function. (getAccessibleContext): Add AccessibleAWTCheckBox to item listeners. 2004-11-30 Sven de Marothy <sven@physto.se> * java/awt/Polygon.java (contains): Reimplemented. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/print/PrinterJob.java: Reformatted. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/image/AffineTransformOp.java, java/awt/image/ColorConvertOp.java, java/awt/image/LookupOp.java, java/awt/image/RescaleOp.java: Added final keywords where they belong. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/CardLayout.java, java/awt/Component.java, java/awt/Font.java, java/awt/image/SinglePixelPackedSampleModel.java: Fixed javadocs and argument names all over. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/image/DataBufferShort.java: Fixed file header. * java/awt/image/DataBufferUShort.java: Likewise. (DataBufferUShort): Throw NullPointerException if dataArray is null. 2004-11-30 Sven de Marothy <sven@physto.se> * java/awt/geom/Arc2D.java (setAngleStart): Corrected (wrong sign on atan2 y parameter). (setAngles): Likewise. (containsAngle): Return false on zero extent, don't include final angle. (contains): Treat OPEN-type arcs like CHORD ones, not as PIE ones. 2004-11-30 Sven de Marothy <sven@physto.se> * java/awt/geom/AffineTransform.java, (inverseTransform): Fixed bug and simplified code. (createTransformedShape): Return null on null parameter. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/color/ICC_ColorSpace.java, java/awt/color/ICC_Profile.java, java/awt/color/ICC_ProfileGray.java, java/awt/color/ICC_ProfileRGB.java: Re-indent copyright header to be standardish. * java/awt/datatransfer/StringSelection.java: Reformatted. * java/awt/geom/Area.java (EPSILON): Made static. (RS_EPSILON): Likewise. (PE_EPSILON): Likewide. 2004-11-30 Sven de Marothy <sven@physto.se> * javax/swing/SwingUtilities.java: (computeDifference): Implemented (computeIntersection): Likewise (computeUnion): Likewise (isRectangleContainingRectangle): Likewise 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/BasicStroke.java, java/awt/Button.java, java/awt/Canvas.java, java/awt/CheckboxMenuItem.java, java/awt/Container.java, java/awt/EventQueue.java, java/awt/FileDialog.java, java/awt/FlowLayout.java, java/awt/FontMetrics.java, java/awt/Graphics.java, java/awt/GridLayout.java, java/awt/KeyboardFocusManager.java, java/awt/Label.java, java/awt/LayoutManager2.java, java/awt/List.java, java/awt/MenuBar.java, java/awt/Scrollbar.java, java/awt/Toolkit.java, java/awt/Window.java, java/awt/datatransfer/DataFlavor.java, java/awt/datatransfer/FlavorTable.java, java/awt/event/ActionListener.java, java/awt/event/HierarchyBoundsAdapter.java, java/awt/geom/Arc2D.java, java/awt/geom/Rectangle2D.java, java/awt/geom/RectangularShape.java, java/awt/im/spi/InputMethod.java, java/awt/image/ByteLookupTable.java, java/awt/image/ColorModel.java, java/awt/image/DirectColorModel.java, java/awt/image/ShortLookupTable.java, java/awt/print/Book.java: Fixed javadocs and method argument names all over. 2004-11-30 Michael Koch <konqueror@gmx.de> * gnu/java/awt/peer/gtk/GdkFontPeer.java (buildString): Optimise String building. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/TextArea.java (AccessibleAWTTextArea, getAccessibleContext): Implement. * java/awt/TextField.java (AccessibleAWTTextField, getAccessibleContext): Implement. 2004-11-30 Tom Tromey <tromey@redhat.com> * Makefile.in: Rebuilt. * Makefile.am (jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.lo): Fixed typo. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/Menu.java (AccessibleAWTMenu, getAccessibleContext): Implement. * java/awt/PopupMenu.java (AccessibleAWTMenu, getAccessibleContext): Implement. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/print/PrinterJob.java (lookupPrintServices, getPrintService, setPrintService): Implement. (lookupStreamPrintServices): Add commented out implementation. (printer): New field. 2004-11-30 Mark Wielaard <mark@klomp.org> * javax/swing/ToolTipManager.java (mouseMoved): Set currentComponent when not yet set. 2004-11-30 Sven de Marothy <sven@physto.se> * java/awt/geom/GeneralPath.java (evaluateCrossings): Fixed epsilon value, should always be nonzero. 2004-11-30 Paul Jenner <psj.home@ntlworld.com> * java/awt/image/Raster.java (createPackedRaster): Implemented. 2004-11-30 Graydon Hoare <graydon@redhat.com> * javax/swing/plaf/basic/BasicTextUI.java: Listen to focus events, indicate focus via caret. * javax/swing/text/GapContent.java (getString): Return substring. * javax/swing/text/PlainDocument.java (reindex): New method. (createDefaultRoot): Call it. (insertUpdate): Likewise. (removeUpdate): Likewise. * javax/swing/text/Utilities.java (drawTabbedText): Always advance on tab and newline, even if no painting happens. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * Makefile.am: List peer JNI header: Java source file dependencies explicitly. Likewise for JNI .lo: JNI header dependencies. * Makefile.in: Regenerate. 2004-11-30 Graydon Hoare <graydon@redhat.com> * Makefile.am: Add entry for BasicTextPaneUI.java * Makefile.in: Regenerate. * gnu/java/awt/peer/gtk/GdkGraphics2D.java (GdkGraphics2D): Set clip after transform. (drawImage): Protect against null image. * gnu/java/awt/peer/gtk/GtkFramePeer.java (setIconImage): Protect against non-GtkImage args. * gnu/java/awt/peer/gtk/GtkToolkit.java (checkImage): Protect against non-GtkImage args. * java/awt/print/PrinterJob.java: (print): Add variant taking PrintRequestAttributeSet. (printDialog): Likewise. * javax/swing/JComponent.java: (transferHandler): New field. (getComponentGraphics): Build new Graphics for each sub-paint. (getTransferHandler): New method. (setTransferHandler): New method. * javax/swing/JDesktopPane.java (setDragMode): Force LIVE_DRAG_MODE. * javax/swing/JMenuItem.java (menuSelectionChanged): Protect against null parent. * javax/swing/JTable.java (setDefaultRenderer): New method. * javax/swing/JTree.java: Get basic ctors and UI working. * javax/swing/JViewport.java (JViewport): Set scroll mode. * javax/swing/RepaintManager.java (addDirtyRegion): Skip empty regions. * javax/swing/ScrollPaneLayout.java (minimumLayoutSize): Do not bound scrollpane minimum by central view minimum. * javax/swing/ToolTipManager.java (showTip): Guard against null component. * javax/swing/TransferHandler.java: Stub out. * javax/swing/plaf/basic/BasicLookAndFeel.java: Add entry for TextPaneUI, change Tree icons to pngs. * javax/swing/plaf/basic/BasicMenuItemUI.java: (installDefaults): Set text position and alignment. (paintMenuItem): Layout icon with normal compound function. * javax/swing/plaf/basic/BasicTableHeaderUI.java: (getMaximumSize): Delete. (getMinimumSize): Delete. (getPreferredSize): Use column model's total width. * javax/swing/plaf/basic/BasicTextPaneUI.java: New file. * javax/swing/plaf/basic/BasicTextUI.java (modelChanged): Make resilient against nulls. * javax/swing/plaf/basic/BasicTreeUI.java: Add some simplistic config / painting functions. * javax/swing/plaf/basic/BasicViewportUI.java (paintSimple): Add new non-backingstore paint mode. (paintBackingStore): Split out backing store code. (paint): Switch on painting mode. * javax/swing/text/SimpleAttributeSet.java (SimpleAttributeSet): Resist nulls. * javax/swing/tree/DefaultTreeCellRenderer.java: Implement. * javax/swing/tree/DefaultTreeModel.java: Partially implement. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c (setFont): Set pango context's description and language. 2004-11-30 Mark Wielaard <mark@klomp.org> * java/awt/image/LookupOp.java: Comments and indentation fixes. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/Checkbox.java (AccessibleAWTCheckBox): Implement. (getAccessibleContext): Implement. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/TextComponent.java (AccessibleAWTTextComponent): Implement. (getIndexAtPoint, getCharacterBounds): New methods. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/Button.java (AccessibleAWTButton): Implement. 2004-11-30 Mark Wielaard <mark@klomp.org> * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c (filenameFilterCallback): Made static. 2004-11-30 Michael Koch <konqueror@gmx.de> * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c (cairoShowGlyphs) Removed. 2004-11-30 Sven de Marothy <sven@physto.se> * gnu/java/awt/color/RgbProfileConverter.java (RgbProfileConverter): Don't invert matrix when reverse CLUT is available. * gnu/java/awt/color/LinearRGBConverter.java: Documentation update. * java/awt/color/ICC_ColorSpace.java: Likewise. * java/awt/color/ICC_Profile.java: Likewise. * java/awt/color/ICC_ProfileGray.java: Likewise. * java/awt/color/ICC_ProfileRGB.java: Likewise. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/MenuItem.java (AccessibleAWTMenuItem): Implement. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/Choice.java (AccessibleAWTChoice): Implement. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/BandedSampleModel.java (scanlineStride): Remove field hiding ComponentSampleModel.scanlineStride. 2004-11-30 Noa Resare <noa@resare.com> * java/awt/geom/GeneralPath.java (currentSegment): Fix typo in transform.transform() invocation. 2004-11-30 Sven de Marothy <sven@physto.se> * gnu/java/awt/peer/gtk/GtkComponentPeer.java (createImage): Created bitmap should be filled with bg color 2004-11-30 Noa Resare <noa@resare.com> * java/awt/Choice.java (add): Implement correct selection behavior when peer == null. (insert): Likewise. (remove): Likewise. 2004-11-30 Mark Wielaard <mark@klomp.org> * gnu/java/awt/peer/gtk/GtkChoicePeer.java (GtkChoicePeer): Call select() when Choice has a selected item. 2004-11-30 Michael Koch <address@bogus.example.com> * jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuBarPeer.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuPeer.c, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c: Fixed method names to start at begin of line. This is desired by GNU coding style guide. 2004-11-30 Michael Koch <konqueror@gmx.de> * gnu/java/awt/peer/gtk/GtkComponentPeer.java (gtkWidgetSetVisible): Unused. Removed. (connectJObject): Likewise. * gnu/java/awt/peer/gtk/GtkScrollPanePeer.java (gtkScrolledWindowSetScrollPosition): Commented out. 2004-11-30 Mark Wielaard <mark@klomp.org> * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c (Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText): Installed and renamed from Java_gnu_java_awt_peer_gtk_GdkGlyphVector_setText. 2004-11-30 Mark Wielaard <mark@klomp.org> * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c (Java_gnu_java_awt_peer_gtk_GdkGlyphVector_setText): Removed. * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c (init_dpi_conversion_factor): Correct prototype. 2004-11-30 Sven de Marothy <sven@physto.se> * java/awt/image/ConvolveOp.java: Added missing copyright notice. 2004-11-30 Robert Schuster <theBohemian@gmx.net> Fixes bug #10908 * gnu/java/beans/IntrospectionIncubator.java: (addMethod): static methods are discarded now, too. 2004-11-30 Mark Wielaard <mark@klomp.org> * Makefile.am (awt_java_source_files): Add new gnu/java/awt/color java source files. * Makefile.in: Regenerated. 2004-11-30 Sven de Marothy <sven@physto.se> * gnu/java/awt/color/CieXyzConverter.java, gnu/java/awt/color/GrayScaleConverter.java, gnu/java/awt/color/SrgbConverter.java, gnu/java/awt/color/ClutProfileConverter.java, gnu/java/awt/color/LinearRGBConverter.java, gnu/java/awt/color/TagEntry.java, gnu/java/awt/color/ColorLookUpTable.java, gnu/java/awt/color/ProfileHeader.java, gnu/java/awt/color/ToneReproductionCurve.java, gnu/java/awt/color/ColorSpaceConverter.java, gnu/java/awt/color/PyccConverter.java, gnu/java/awt/color/GrayProfileConverter.java, gnu/java/awt/color/RgbProfileConverter.java: New files. * java/awt/color/ICC_ColorSpace.java, java/awt/color/ICC_Profile.java, java/awt/color/ICC_ProfileGray.java, java/awt/color/ICC_ProfileRGB.java: Implemented (sans PhotoYCC color space). 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/AffineTransformOp.java (filter): Implement bilinear interpolation for Rasters. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/IndexColorModel.java (IndexColorModel): Actually use the provided colormap. Throw documented exceptions. Document exceptions. 2004-11-30 Paul Jenner <psj.home@ntlworld.com> * java/awt/image/IndexColorModel.java (IndexColorModel): Fix constructor. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/AffineTransformOp.java: Add TYPE_BICUBIC. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/AffineTransformOp.java (filter): Implement Raster filtering. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/ComponentSampleModel.java (getDataElements, setDataElements): Implement SHORT, FLOAT, and INT transfer types. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * java/awt/Font.java (name): New field. (size): Likewise. (style): Likewise. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/Raster.java (createBandedRaster): Implement. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/ConvolveOp.java: New class. * Makefile.am: Add ConvolveOp. * Makefile.in: Regenerate. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/RescaleOp.java (BandCombineOp, ColorConvertOp, LookupOp, RescaleOp): Fix loop bounds. 2004-11-30 jlquinn <jlquinn@optonline.net> * Makefile.am: Fix typo in BandCombineOp. * Makefile.in: Regenerate. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/BandCombineOp.java: New class. * Makefile.am: Add BandCombineOp. * Makefile.in: Regenerate. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/LookupOp.java: New class. * Makefile.am: Add LookupOp. * Makefile.in: Regenerate. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/SampleModel.java (createSubsetSampleModel): Add javadocs. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/ColorModel.java (cloneColorModel): Fix line wrap. Use Boolean.valueOf. 2004-11-30 Michael Koch <konqueror@gmx.de> * gnu/java/awt/peer/gtk/GdkGraphics2D.java (releasePeerGraphicsResource): Fixed typo in method name. * gnu/java/awt/peer/gtk/GdkFontPeer.java (finalize): Fixed typo in releasePeerGraphicsResource. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/font/TextAttribute.java (RUN_DIRECTION_LTR): Initialie with static value instead of calculating it. (RUN_DIRECTION_RTL): Likewise. (STRIKETHROUGH_ON): Likewise. (SWAP_COLORS_ON): Likewise. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/ColorConvertOp.java: New class. * java/awt/image/ColorModel.java (cloneColorModel): New method. * Makefile.am: Add ColorConvertOp. * Makefile.in: Regenerate. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * java/awt/DefaultKeyboardFocusManager.java (dispatchEvent): Track Window focus owner on FOCUS_GAINED events. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c (nativeSetIconImage): Rename to nativeSetIconImageFromDecoder. 2004-11-30 Andreas Tobler <a.tobler@schweiz.ch> * jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c (Java_gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_nativeRun): Fix pointer warning. 2004-11-30 Andreas Tobler <a.tobler@schweiz.ch> * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c (Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetFilenameFilter): Fix pointer warning. * jni/gtk-peer/gtkpeer.h: Introduce widget_union to fix type punned warnings. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c (Java_gnu_java_awt_peer_gtk_GdkGraphics_clearRect): Use widget_union to fix type punned pointer warning. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c (pre_event_handler): Likewise. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c (window_get_new_state): Introduce unions to fix warnings as above. (window_property_changed_cb): Likewise. (window_active_state_change_cb): Mark unused variables unused. (window_focus_state_change_cb): Likewise. (window_focus_in_cb): Likewise. (window_focus_out_cb): Likewise. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c (Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont): Convert PangoFontMap correctly with PANGO_FT2FONT_MAP macro. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JMenuBar.java (updateUI): Simplified. * javax/swing/tree/DefaultTreeSelectionModel.java: Reorganized import statements. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/font/TextAttribute.java, javax/swing/JComponent.java, javax/swing/JInternalFrame.java, javax/swing/table/TableColumn.java, javax/swing/text/StyleConstants.java: Replaced "new Boolean(boolean)" with "Boolean.valueOf(boolean)". 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/tree/DefaultTreeCellEditor.java, javax/swing/tree/DefaultTreeModel.java, javax/swing/tree/DefaultTreeSelectionModel.java: Jalopied. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/tree/DefaultTreeCellEditor.java (EditorContainer.EditorContainer): Fixed arguments. (EditorContainer.EditorContainer): New method. (DefaultTextField.DefaultTextField): Fixed arguments, implemented. (DefaultTextField.getBorder): Implemented. (listenerList): New field. (addCellEditorListener): Implemented. (removeCellEditorListener): Implemented. (getCellEditorListeners): New method. * javax/swing/tree/DefaultTreeModel.java (addTreeModelListener): Fixed javadoc. (removeTreeModelListener): Likewise. (getTreeModelListeners): New method. (fireTreeNodesChanged): Implemented. (fireTreeNodesInserted): Likewise. (fireTreeNodesRemoved): Likewise. (fireTreeStructureChanged): Likewise. (getListeners): Fixed javadoc. * javax/swing/tree/DefaultTreeSelectionModel.java (addTreeSelectionListener): Implemented. (removeTreeSelectionListener): Likewise. (fireValueChanged): Likewise. (getListeners): Likewise. (addPropertyChangeListener): Likewise. (removePropertyChangeListener): Likewise. (getTreeSelectionListeners): New method. (getPropertyChangeListeners): Likewise. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/plaf/basic/BasicScrollBarUI.java (maximumThumbSize): Removed static keyword. (minimumThumbSize): Likewise. * javax/swing/plaf/basic/BasicInternalFrameTitlePane.java (CloseAction): Made public. (IconifyAction): Likewise. (MaximizeAction): Likewise. (MoveAction): Likewise. (RestoreAction): Likewise. (SizeAction): Likewise. (SystemMenuBar): Likewise. * javax/swing/plaf/basic/BasicSliderUI.java (TrackListener): Likewise. * javax/swing/plaf/basic/BasicSplitPaneUI.java (KeyboardDownRightHandler): Likewise. (KeyboardEndHandler): Likewise. (KeyboardHomeHandler): Likewise. (KeyboardResizeToggleHandler): Likewise. (KeyboardUpLeftHandler): Likewise. (PropertyHandler): Likewise. * javax/swing/plaf/basic/BasicTabbedPaneUI.java (PropertyChangeHandler): Likewise. (TabSelectionHandler): Likewise. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/text/JTextComponent.java (getKeymap): Made public. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JEditorPane.java (getStream): Throws IOException. (read): Likewise. * javax/swing/JRootPane.java (createContentPane): Fixed return type. * javax/swing/JSpinner.java (commitEdit): Throws ParseException. * javax/swing/plaf/metal/MetalLookAndFeel.java (serialVersionUID): New field. * javax/swing/table/TableColumn.java (resizedPostingDisableCount): Added @deprecated tag. (disableResizedPosting): Likewise. (enableResizedPosting): Likewise. * javax/swing/text/Document.java (TitleProperty): Fixed value. * javax/swing/tree/TreeCellEditor.java (TreeCellEditor): Extends CellEditor. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JWindow.java javax/swing/SpinnerModel.java javax/swing/Timer.java javax/swing/event/MenuKeyEvent.java javax/swing/plaf/basic/BasicButtonUI.java javax/swing/plaf/basic/BasicIconFactory.java javax/swing/plaf/basic/BasicTabbedPaneUI.java javax/swing/text/AttributeSet.java javax/swing/text/Highlighter.java javax/swing/text/StyleConstants.java javax/swing/tree/TreeCellEditor.java: Removed redundant and reordered modifiers. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/plaf/basic/BasicToolTipUI.java: Reformatted copyright header. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/AbstractAction.java, javax/swing/AbstractButton.java, javax/swing/AbstractCellEditor.java, javax/swing/AbstractListModel.java, javax/swing/AbstractSpinnerModel.java, javax/swing/ActionMap.java, javax/swing/BorderFactory.java, javax/swing/Box.java, javax/swing/ButtonModel.java, javax/swing/CellEditor.java, javax/swing/CellRendererPane.java, javax/swing/DefaultBoundedRangeModel.java, javax/swing/DefaultButtonModel.java, javax/swing/DefaultCellEditor.java, javax/swing/DefaultDesktopManager.java, javax/swing/DefaultListCellRenderer.java, javax/swing/DefaultListSelectionModel.java, javax/swing/DefaultSingleSelectionModel.java, javax/swing/GrayFilter.java, javax/swing/InputMap.java, javax/swing/JApplet.java, javax/swing/JCheckBoxMenuItem.java, javax/swing/JColorChooser.java, javax/swing/JComboBox.java, javax/swing/JComponent.java, javax/swing/JDesktopPane.java, javax/swing/JDialog.java, javax/swing/JEditorPane.java, javax/swing/JFileChooser.java, javax/swing/JFormattedTextField.java, javax/swing/JFrame.java, javax/swing/JInternalFrame.java, javax/swing/JLabel.java, javax/swing/JLayeredPane.java, javax/swing/JList.java, javax/swing/JMenu.java, javax/swing/JMenuBar.java, javax/swing/JMenuItem.java, javax/swing/JOptionPane.java, javax/swing/JPanel.java, javax/swing/JPasswordField.java, javax/swing/JPopupMenu.java, javax/swing/JRadioButtonMenuItem.java, javax/swing/JRootPane.java, javax/swing/JSpinner.java, javax/swing/JSplitPane.java, javax/swing/JTabbedPane.java, javax/swing/JTable.java, javax/swing/JTextArea.java, javax/swing/JTextPane.java, javax/swing/JToggleButton.java, javax/swing/JToolBar.java, javax/swing/JToolTip.java, javax/swing/JTree.java, javax/swing/JViewport.java, javax/swing/ListModel.java, javax/swing/LookAndFeel.java, javax/swing/MenuSelectionManager.java, javax/swing/ProgressMonitorInputStream.java, javax/swing/RepaintManager.java, javax/swing/RootPaneContainer.java, javax/swing/ScrollPaneLayout.java, javax/swing/SpringLayout.java, javax/swing/SwingUtilities.java, javax/swing/Timer.java, javax/swing/ToolTipManager.java, javax/swing/UIDefaults.java, javax/swing/UIManager.java, javax/swing/border/MatteBorder.java, javax/swing/colorchooser/AbstractColorChooserPanel.java, javax/swing/colorchooser/ColorSelectionModel.java, javax/swing/colorchooser/DefaultColorSelectionModel.java, javax/swing/colorchooser/DefaultHSBChooserPanel.java, javax/swing/colorchooser/DefaultPreviewPanel.java, javax/swing/colorchooser/DefaultRGBChooserPanel.java, javax/swing/colorchooser/DefaultSwatchChooserPanel.java, javax/swing/event/AncestorEvent.java, javax/swing/event/HyperlinkEvent.java, javax/swing/event/InternalFrameEvent.java, javax/swing/event/MenuDragMouseEvent.java, javax/swing/event/TableColumnModelEvent.java, javax/swing/event/TableModelEvent.java, javax/swing/event/TreeExpansionEvent.java, javax/swing/event/TreeModelEvent.java, javax/swing/event/TreeSelectionEvent.java, javax/swing/event/TreeWillExpandListener.java, javax/swing/event/UndoableEditEvent.java, javax/swing/filechooser/FileView.java, javax/swing/plaf/BorderUIResource.java, javax/swing/plaf/ComponentUI.java, javax/swing/plaf/FileChooserUI.java, javax/swing/plaf/IconUIResource.java, javax/swing/plaf/ListUI.java, javax/swing/plaf/PopupMenuUI.java, javax/swing/plaf/SplitPaneUI.java, javax/swing/plaf/TabbedPaneUI.java, javax/swing/plaf/TextUI.java, javax/swing/plaf/TreeUI.java, javax/swing/plaf/basic/BasicArrowButton.java, javax/swing/plaf/basic/BasicBorders.java, javax/swing/plaf/basic/BasicButtonUI.java, javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.java, javax/swing/plaf/basic/BasicColorChooserUI.java, javax/swing/plaf/basic/BasicComboBoxEditor.java, javax/swing/plaf/basic/BasicComboBoxRenderer.java, javax/swing/plaf/basic/BasicComboBoxUI.java, javax/swing/plaf/basic/BasicComboPopup.java, javax/swing/plaf/basic/BasicDesktopIconUI.java, javax/swing/plaf/basic/BasicDesktopPaneUI.java, javax/swing/plaf/basic/BasicIconFactory.java, javax/swing/plaf/basic/BasicInternalFrameTitlePane.java, javax/swing/plaf/basic/BasicInternalFrameUI.java, javax/swing/plaf/basic/BasicListUI.java, javax/swing/plaf/basic/BasicLookAndFeel.java, javax/swing/plaf/basic/BasicMenuBarUI.java, javax/swing/plaf/basic/BasicMenuItemUI.java, javax/swing/plaf/basic/BasicMenuUI.java, javax/swing/plaf/basic/BasicOptionPaneUI.java, javax/swing/plaf/basic/BasicPopupMenuSeparatorUI.java, javax/swing/plaf/basic/BasicPopupMenuUI.java, javax/swing/plaf/basic/BasicProgressBarUI.java, javax/swing/plaf/basic/BasicRadioButtonMenuItemUI.java, javax/swing/plaf/basic/BasicRootPaneUI.java, javax/swing/plaf/basic/BasicScrollBarUI.java, javax/swing/plaf/basic/BasicSeparatorUI.java, javax/swing/plaf/basic/BasicSliderUI.java, javax/swing/plaf/basic/BasicSpinnerUI.java, javax/swing/plaf/basic/BasicSplitPaneDivider.java, javax/swing/plaf/basic/BasicSplitPaneUI.java, javax/swing/plaf/basic/BasicTabbedPaneUI.java, javax/swing/plaf/basic/BasicTableHeaderUI.java, javax/swing/plaf/basic/BasicTableUI.java, javax/swing/plaf/basic/BasicTextAreaUI.java, javax/swing/plaf/basic/BasicTextFieldUI.java, javax/swing/plaf/basic/BasicTextUI.java, javax/swing/plaf/basic/BasicToolBarSeparatorUI.java, javax/swing/plaf/basic/BasicToolBarUI.java, javax/swing/plaf/basic/BasicToolTipUI.java, javax/swing/plaf/basic/BasicTreeUI.java, javax/swing/plaf/basic/BasicViewportUI.java, javax/swing/plaf/basic/ComboPopup.java, javax/swing/table/AbstractTableModel.java, javax/swing/table/DefaultTableCellRenderer.java, javax/swing/table/DefaultTableColumnModel.java, javax/swing/table/DefaultTableModel.java, javax/swing/table/JTableHeader.java, javax/swing/table/TableCellEditor.java, javax/swing/table/TableCellRenderer.java, javax/swing/table/TableColumn.java, javax/swing/table/TableColumnModel.java, javax/swing/text/AbstractDocument.java, javax/swing/text/Caret.java, javax/swing/text/DefaultCaret.java, javax/swing/text/DefaultEditorKit.java, javax/swing/text/DefaultHighlighter.java, javax/swing/text/EditorKit.java, javax/swing/text/JTextComponent.java, javax/swing/text/LayeredHighlighter.java, javax/swing/text/PasswordView.java, javax/swing/text/SimpleAttributeSet.java, javax/swing/text/StyleConstants.java, javax/swing/text/StyleContext.java, javax/swing/text/StyledEditorKit.java, javax/swing/text/TextAction.java, javax/swing/text/View.java, javax/swing/tree/AbstractLayoutCache.java, javax/swing/tree/DefaultTreeCellRenderer.java, javax/swing/tree/DefaultTreeModel.java, javax/swing/tree/DefaultTreeSelectionModel.java, javax/swing/tree/FixedHeightLayoutCache.java, javax/swing/tree/TreeCellRenderer.java, javax/swing/tree/TreeSelectionModel.java, javax/swing/tree/VariableHeightLayoutCache.java, javax/swing/undo/AbstractUndoableEdit.java, javax/swing/undo/UndoableEditSupport.java: Imports cleaned up. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/Container.java, java/awt/Font.java, java/awt/font/TextLayout.java: Imports cleaned up. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/AbstractButton.java (getLabel): Added @deprecated tag. (setLabel): Likewise. * javax/swing/FocusManager.java (disableSwingFocusManager): Likewise. (isFocusManagerEnabled): Likewise. * javax/swing/JComponent.java (isManagingFocus): Added version to @deprecated tag. (getNextFocusableComponent): Moved @deprecated tag to bottom of javadoc. (getConditionForKeyStroke): Likewise. (getActionForKeyStroke): Likewise. * javax/swing/JDesktopPane.java (LIVE_DRAG_MODE): Added @specnote tag. (OUTLINE_DRAG_MODE): Likewise. * javax/swing/JInternalFrame.java (MENU_BAR_PROPERTY): Fixed value. (getMenuBar): Added @deprecated tag. (setMenuBar): Likewise. * javax/swing/JViewport.java (isBackingStoreEnabled): Likewise. (setBackingStoreEnabled): Likewise. * javax/swing/plaf/basic/BasicDesktopPaneUI.java (closeKey): Likewise. (maximizeKey): Likewise. (minimizeKey): Likewise. (navigateKey): Likewise. (navigateKey2): Likewise. * javax/swing/plaf/basic/BasicInternalFrameUI.java (openMenuKey): Likewise. * javax/swing/plaf/basic/BasicSplitPaneUI.java (keyboardDownRightListener): Likewise. (keyboardEndListener): Likewise. (keyboardHomeListener): Likewise. (keyboardResizeToggleListener): Likewise. (keyboardUpLeftListener): Likewise. (dividerResizeToggleKey): Likewise. (downKey): Likewise. (endKey): Likewise. (homeKey): Likewise. (leftKey): Likewise. (rightKey): Likewise. (upKey): Likewise. (createKeyboardUpLeftListener): Likewise. (createKeyboardDownRightListener): Likewise. (createKeyboardHomeListener): Likewise. (createKeyboardEndListener): Likewise. (createKeyboardResizeToggleListener): Likewise. (getDividerBorderSize): Likewise. * javax/swing/plaf/basic/BasicTabbedPaneUI.java (downKey): Likewise. (leftKey): Likewise. (rightKey): Likewise. (upKey): Likewise. 2004-11-30 Andreas Tobler <a.tobler@schweiz.ch> * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c (Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_create): Use the GTK_TEXT_VIEW macro. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c (connect_awt_hook_cb): Mark unused variable unused. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c (selection_get): Do the cast right. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkChoicePeer.c (Java_gnu_java_awt_peer_gtk_GtkChoicePeer_create): According to the gtk API gtk_combo_box_new_text actually returns a GtkWidget. Remove unused var menu. (selection_changed): Remove unused value. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c (Java_gnu_java_awt_peer_gtk_GtkButtonPeer_setNativeBounds): Fix pointer warning with using an intermediate variable. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c (area_updated): Fix unused var warning for BE archs. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c (Java_gnu_java_awt_peer_gtk_GdkGraphics_connectSignals): Remove unused var. (realize_cb): Mark unused variable unused. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c (seek_glyphstring_idx): Fix a C90 warning. * jni/gtk-peer/gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c (Java_gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_nativeRun): Mark unused arguments unused. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c (Java_gnu_java_awt_peer_gtk_GdkGlyphVector_initState), (Java_gnu_java_awt_peer_gtk_GdkGlyphVector_setGlyphCodes), (Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphCharIndex), (Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphIsHorizontal): Likewise. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c (Java_gnu_java_awt_peer_gtk_GdkFontMetrics_getPeerFontMetrics), (Java_gnu_java_awt_peer_gtk_GdkFontMetrics_getPeerTextMetrics): Likewise. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c (Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetFilenameFilter): Likewise. (filenameFilterCallback): Remove unused var. (handle_response): Declare str_fileName and remove last else statement. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c: New File. (nativeGetNumFontsFamilies) New function. (nativeGetFontFamilies) Likewise. * gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java (getAvailableFontFamilyNames): Implement. * Makefile.am (gtk_c_source_files): Add GdkGraphicsEnvironment.c. * Makefile.in: Regenerate. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * gnu/java/awt/peer/ClasspathFontPeer.java (setStandardAttributes(String,Map)): If size attribute doesn't exist, default to size 12. Clamp size value to a minimum of 1. 2004-11-30 Jeroen Frijters <jeroen@frijters.net> * javax/swing/JDialog.java (decorated): Likewise. * javax/swing/JFrame.java (defaultLookAndFeelDecorated): Likewise. 2004-11-30 Jeroen Frijters <jeroen@frijters.net> * javax/swing/plaf/basic/BasicToolBarUI.java (offset, regular): Made final. * javax/swing/plaf/basic/BasicScrollBarUI.java (DECREASE_HIGHLIGHT, INCREASE_HIGHLIGHT, NO_HIGHLIGHT, POSITIVE_SCROLL, NEGATIVE_SCROLL): Made final. 2004-11-30 Michael Koch <konqueror@gmx.de> * gnu/java/awt/BitwiseXORComposite.java, gnu/java/awt/ClasspathToolkit.java, gnu/java/awt/image/XBMDecoder.java, gnu/java/awt/peer/GLightweightPeer.java, gnu/java/awt/peer/gtk/GdkGlyphVector.java: Reorganized import statements. 2004-11-30 Jeroen Frijters <jeroen@frijters.net> * java/awt/Button.java (next_button_number): Removed useless initializer. * java/awt/Frame.java (next_frame_number): Likewise. * java/awt/Panel.java (next_panel_number): Likewise, * java/awt/Scrollbar.java (next_scrollbar_number): Likewise. * java/awt/TextArea.java (next_text_number): Likewise. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/image/ByteLookupTable.java (ByteLookupTable) :Fixed HTML entities in javadocs. (lookupPixel): Fix case when dst is null. * java/awt/image/ShortLookupTable.java (ShortLookupTable) :Fixed HTML entities in javadocs. (lookupPixel): Fix case when dst is null. * java/awt/image/DataBufferByte.java, java/awt/image/DataBufferDouble.java, java/awt/image/DataBufferFloat.java, java/awt/image/DataBufferInt.java, java/awt/image/DataBufferShort.java, java/awt/image/DataBufferUShort.java: Fix initialization of bankData in constructors. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * gnu/java/awt/peer/gtk/GtkButtonPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c (setNativeBounds): Set GtkEventBox, GtkButton and GtkLabel size requests. * gnu/java/awt/peer/gtk/GtkComponentPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c (setNativeBounds): Make package private. Set size request even if GTK parent is NULL. * gnu/java/awt/peer/gtk/GtkLabelPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c (setNativeBounds): Set GtkEventBox and GtkLabel size requests. 2004-11-30 Mark Wielaard <mark@klomp.org> Workaround for bug #17952. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c (request_frame_extents): Check window->window != NULL. 2004-11-30 Mark Wielaard <mark@klomp.org> * jni/gtk-peer/gdkfont.h: Include gtkpeer.h not gtkcairopeer.h. 2004-11-30 Andreas Tobler <a.tobler@schweiz.ch> * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c: Use native_text_layout_state_table here. * jni/gtk-peer/gdkfont.h: Mark native_text_layout_state_table extern. 2004-11-30 Mark Wielaard <mark@klomp.org> * native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c (setChars): Only call pango_itemize() when vec->glyphitems != NULL. Only call pango_shape() when gi->glyphs->num_glyphs > 0. 2004-11-30 Michael Koch <konqueror@gmx.de> * gnu/java/awt/peer/gtk/GtkToolkit.java: Merged import statements. 2004-11-30 Michael Koch <konqueror@gmx.de> * gnu/java/awt/peer/gtk/GdkGraphics2D.java (isBufferedImageGraphics): Simplified. 2004-11-30 Paul Jenner <psj.home@ntlworld.com> * javax/swing/JTree.java (isRootVisible): Fixed typo in method name. * javax/swing/JScrollBar.java (setValues): Likewise. * javax/swing/JScrollPane.java (createScrollListener): Call JScrollBar.setValues. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * gnu/java/awt/peer/gtk/GtkContainerPeer.java (endValidate): Don't call setParentAndBounds on GtkWindowPeers. * java/awt/Component.java (static): Don't set default keyboard focus manager. * java/awt/KeyboardFocusManager.java (getCurrentKeyboardFocusManager): If current keyboard focus manager is null set a default. * gnu/java/awt/peer/gtk/GtkButtonPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c (gtkWidgetSetBackground): New method. (block_expose_events_cb): New function. (connectSignals): Block the AWT's expose event processing on button press and release. (gtkSetLabel): Set text on proper widget. (gtkWidgetModifyFont): Modify font on proper widget. (gtkWidgetSetBackground): Set normal, active and prelight colours. (gtkWidgetSetForeground): Set forground colour of proper widget. (gtkActivate): Activate the correct widget. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c (clearRect): Only clear rectangle if the backing component is not an event box. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c (beginNativeRepaintID): New variable. (endNativeRepaintID): Likewise. (gtkInit): Initialize new fields with method IDs. * jni/gtk-peer/gtkpeer.h (beginNativeRepaintID): Declare extern. (endNativeRepaintID): Likewise. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * javax/swing/JList.java (init): Revert accidental commit. * gnu/java/awt/peer/gtk/GdkGraphics.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c (GdkGraphics): Call initComponentGraphics or connectSignals depending on component's realization status. (realize_cb): New function. (initComponentGraphics): New method. (connectSignals): New method. (clipRect): Return immediately if component is not realized. (setClip): Likewise. (translate): Likewise. (drawImage variants): Return false immediately if component is not realized. * gnu/java/awt/peer/gtk/GdkGraphics2D.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c (connectSignals): New method. (GdkGraphics2D): Call initComponentGraphics2D or connectSignals depending on component's realization status. Move other initialization calls to ... (initComponentGraphics2D): New method. (realize_cb): New function. (cairoSetMatrix): Return immediately if gr is NULL. (cairoNewPath): Likewise. (cairoRectangle): Likewise. (cairoClip): Likewise. * gnu/java/awt/peer/gtk/GtkComponentPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c (gtkWidgetRepaintArea): Remove method. (isRealized): New method. (GtkComponentPeer): Move setParent, connectJObject and setCursor calls to setParentAndBounds. Call setParentAndBounds. (setParentAndBounds): New method. (setComponentBounds): Return immediately if bounds are all zero. (repaint): Remove call to gtkWidgetRepaintArea. Return immediately if requested paint region is 0x0. (setCursor): New method. (gtkWidgetSetParent): Only set widget's parent if its parent is currently NULL. (setNativeBounds): Only set widget's bounds if it has a parent. (connectSignals): Don't call gtk_widget_realize. Connect "realize" signal to connect_awt_hook_cb handler. * gnu/java/awt/peer/gtk/GtkContainerPeer.java (isValidating): New field. (beginValidate): Set isValidating true. (endValidate): Set parents and bounds for children first, then for this. Set isValidating false. * gnu/java/awt/peer/gtk/GtkFileDialogPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFileDialogPeer.c (connectJObject): Remove method. (connectSignals): Don't call gtk_widget_realize. * gnu/java/awt/peer/gtk/GtkListPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c (connectJObject): Remove method. (connectSignals): Don't call gtk_widget_realize. * gnu/java/awt/peer/gtk/GtkPanelPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c (connectJObject): Remove method. * gnu/java/awt/peer/gtk/GtkScrollbarPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollBarPeer.c (connectJObject): Remove method. * gnu/java/awt/peer/gtk/GtkWindowPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c (create): Don't call gtk_widget_realize. (connectJObject): Remove method. (connectSignals): Don't call gtk_widget_realize. Connect "realize" signal to connect_awt_hook_cb handler. (nativeSetBounds): Don't attempt to move GDK window if it is NULL. * java/awt/Container.java (addImpl): Don't call comp.addNotify if peer is not null. (validateTree): Create peers for all children before calling doLayout. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c (connectSignals): Don't call gtk_widget_realize. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c (connect_awt_hook_cb): New function. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c (initComponentGraphicsID): New variable. (initComponentGraphics2DID): Likewise. (setCursorID): Likewise. (gtkInit): Initialize new fields with method IDs. * jni/gtk-peer/gtkpeer.h (initComponentGraphicsID): Declare extern. (initComponentGraphics2DID): Declare extern. (setCursorID): Likewise. (connect_awt_hook_cb): Declare function. 2004-11-30 Michael Koch <konqueror@gmx.de> * gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java, gnu/java/awt/peer/gtk/GdkGlyphVector.java, gnu/java/awt/peer/gtk/GdkGraphics2D.java, gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java, gnu/java/awt/peer/gtk/GdkPixbufDecoder.java, gnu/java/awt/peer/gtk/GtkButtonPeer.java, gnu/java/awt/peer/gtk/GtkClipboard.java, gnu/java/awt/peer/gtk/GtkDialogPeer.java, gnu/java/awt/peer/gtk/GtkFileDialogPeer.java, gnu/java/awt/peer/gtk/GtkFontPeer.java, gnu/java/awt/peer/gtk/GtkListPeer.java, gnu/java/awt/peer/gtk/GtkMenuItemPeer.java, gnu/java/awt/peer/gtk/GtkToolkit.java, gnu/java/awt/peer/gtk/GtkWindowPeer.java: Import statements reworked. Some little reformattings. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/image/AffineTransformOp.java (TYPE_BILINEAR): Initialize with 2. * java/awt/print/Printable.java: Jalopied. (PAGE_EXISTS): Initialize with 0; (NO_SUCH_PAGE): Initialized with 1. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * Makefile.am: Add BufferedImageFilter.java. * Makefile.in: Regenerate. 2004-11-30 Graydon Hoare <graydon@redhat.com> * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c (install_font_peer): Minor bug fixes to track cairo font semantics. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/BufferedImageFilter.java: Implement. 2004-11-30 Graydon Hoare <graydon@redhat.com> * Makefile.am (jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c) (jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c) (gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java) (gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java): Remove. (jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c) (jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c) (gnu/java/awt/peer/gtk/GdkTextLayout.java) (gnu/java/awt/peer/gtk/GdkFontPeer.java) (gnu/java/awt/peer/ClasspathTextLayoutPeer.java): Add * Makefile.in: Regenerate. * gnu/awt/xlib/XToolkit.java (getClasspathTextLayoutPeer): Add stub. * gnu/java/awt/ClasspathToolkit.java (getClasspathTextLayoutPeer) Add. * gnu/java/awt/peer/ClasspathFontPeer.java (copyStyleToAttrs) (copySizeToAttrs): Make public. * gnu/java/awt/peer/ClasspathTextLayoutPeer.java: New file. * gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java: Remove. * gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java: Remove. * gnu/java/awt/peer/gtk/GdkFontMetrics.java: Rewrite. * gnu/java/awt/peer/gtk/GdkFontPeer.java: New file. * gnu/java/awt/peer/gtk/GdkGlyphVector.java: Adjust type names. * gnu/java/awt/peer/gtk/GdkGraphics.java (getFontPeer): New function. (drawString): Pass font peer to native side. * gnu/java/awt/peer/gtk/GdkGraphics2D.java (cairoSetFont) (cairoShowGlyphs) (PainterThread): Remove. (GdkGraphics2D): Set hints during construction. (shifted) (walkPath) (draw) (setRenderingHint) (setRenderingHints): Reimplement normalization logic. (getDefaultHints) (updateBufferedImage) (isBufferedImageGraphics) (updateImagePixels) (drawImage): Make final. (drawImage): Always paint synchronously. (drawString) (drawGlyphVector): Rewrite. (releasePeerGraphicResource) (getPeerTextMetrics) (getPeerFontMetrics) (drawGdkGlyphVector) (drawGdkTextLayout) (cairoDrawGdkGlyphVector) (cairoDrawGdkTextLayout) (cairoDrawString) (getFontPeer): New functions. * gnu/java/awt/peer/gtk/GdkTextLayout.java: New file. * gnu/java/awt/peer/gtk/GtkComponentPeer.java (getFontMetrics): Get metrics via toolkit, to hit cache. * gnu/java/awt/peer/gtk/GtkTextAreaPeer.java: Use getFontMetrics. * gnu/java/awt/peer/gtk/GtkTextFieldPeer.java: Likewise. * gnu/java/awt/peer/gtk/GtkToolkit.java (LRUCache): New class. (fontCache) (metricsCache) (imageCache): New members. (getFontMetrics) (getImage) (getClasspathFontPeer): Use caches. (getFontPeer): Route through getClasspathFontPeer. * java/awt/Font.java (attrsToMap): Remove, adjust ctors. * java/awt/font/TextLayout.java: Implement in terms of peer. * javax/swing/plaf/basic/BasicSliderUI.java (paintThumb): Use polyline rather than polygon. * javax/swing/plaf/basic/BasicGraphicsUtils.java: Update comment but, alas, still do not switch to using TextLayouts. * javax/swing/text/Utilities.java (drawTabbedText): Draw text run-at-a-time, not char-at-a-time. * jni/gtk-peer/gdkfont.h: Publicize some of the font interface, add layout table. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c: * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c: Remove files. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontMetrics.c: Rewrite to incorporate brains of old GdkClasspathFontPeerMetrics. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c: Rewrite to incorporate brains of old GdkClasspathFontPeer. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c: New file. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c (drawString): Rewrite to use persistent layout in peer font. Comment out extraneous gdk_flush calls. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c (metrics_cairo) (metrics_surface): New static variables. (paint_glyph_run) (install_font_peer): New helper functions. (releasePeerGraphicResource) (getPeerTextMetrics) (getPeerFontMetrics) (cairoDrawGdkTextLayout) (cairoDrawGdkGlyphVector): New native methods. (cairoDrawString): Rewrite, leaving layout-based version commented out for the time being. * jni/gtk-peer/gtkpeer.h (graphics): Add fields for pango stuff. 2004-11-30 David Gilbert <david.gilbert@object-refinery.com> * java/awt/geom/AffineTransform.java: Fixed javadocs overall. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/ComponentColorModel.java: Remove FIXME comment since it's correct. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/IndexColorModel.java: Fix use of immutable BigIntegers. 2004-11-30 Tom Tromey <tromey@redhat.com> * javax/swing/plaf/basic/BasicOptionPaneUI.java (MessageIcon): Renamed from 'messageIcon'. (errorIcon, infoIcon, warningIcon, questionIcon): Updated. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/RescaleOp.java: Fix formatting. 2004-11-30 Olga Rodimina <rodimina@redhat.com> * javax/swing/plaf/basic/BasicComboPopup.java (SCROLL_DOWN): made final. (SCROLL_UP): made final. 2004-11-30 Olga Rodimina <rodimina@redhat.com> * javax/swing/plaf/basic/BasicComboPopup.java: Added javadocs for undocumented fields. (show): scroll down to the selected item and highlight selected item. (startAutoScrolling): Implemented. (stopAutoScrolling): Implemented. (autoScrollUp): Implemented. (autoScrollDown): Implemented. (InvocationMouseHandler.mouseReleased): Implemented. (InvocationMouseMotionHandler.mouseDragged): Implemented. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/RescaleOp.java: Implement. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/IndexColorModel.java (getRGBs, convertToIntDiscrete): Implement. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/IndexColorModel.java: Add class docs. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/IndexColorModel.java (isValid, getValidPixels): Implement. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/MenuBar.java, java/awt/peer/MenuBarPeer.java: Revert accidentally commited changes. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/AWTKeyStroke.java, java/awt/Canvas.java, java/awt/CardLayout.java, java/awt/CheckboxMenuItem.java, java/awt/Component.java, java/awt/Container.java, java/awt/DefaultKeyboardFocusManager.java, java/awt/EventDispatchThread.java, java/awt/FileDialog.java, java/awt/FlowLayout.java, java/awt/Font.java, java/awt/Frame.java, java/awt/Graphics2D.java, java/awt/GraphicsEnvironment.java, java/awt/GridBagConstraints.java, java/awt/GridBagLayout.java, java/awt/GridLayout.java, java/awt/Image.java, java/awt/KeyboardFocusManager.java, java/awt/Label.java, java/awt/List.java, java/awt/MediaTracker.java, java/awt/Menu.java, java/awt/MenuBar.java, java/awt/MenuComponent.java, java/awt/Panel.java, java/awt/PopupMenu.java, java/awt/ScrollPane.java, java/awt/Scrollbar.java, java/awt/SystemColor.java, java/awt/TextArea.java, java/awt/TextField.java, java/awt/Toolkit.java, java/awt/Window.java, java/awt/color/ICC_Profile.java, java/awt/datatransfer/DataFlavor.java, java/awt/datatransfer/StringSelection.java, java/awt/datatransfer/SystemFlavorMap.java, java/awt/dnd/Autoscroll.java, java/awt/dnd/DropTarget.java, java/awt/dnd/DropTargetContext.java, java/awt/dnd/DropTargetDragEvent.java, java/awt/dnd/peer/DropTargetContextPeer.java, java/awt/event/AdjustmentEvent.java, java/awt/event/InputEvent.java, java/awt/event/InvocationEvent.java, java/awt/event/KeyEvent.java, java/awt/event/MouseEvent.java, java/awt/font/TextLayout.java, java/awt/geom/GeneralPath.java, java/awt/geom/Point2D.java, java/awt/im/InputContext.java, java/awt/im/spi/InputMethodContext.java, java/awt/image/AffineTransformOp.java, java/awt/image/BufferedImage.java, java/awt/image/ColorModel.java, java/awt/image/ComponentColorModel.java, java/awt/image/CropImageFilter.java, java/awt/image/DirectColorModel.java, java/awt/image/MemoryImageSource.java, java/awt/image/PackedColorModel.java, java/awt/image/PixelGrabber.java, java/awt/image/RasterOp.java, java/awt/peer/MenuBarPeer.java: Some fixes for checkstyle. Import statement and modifier order redordering. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JTable.java (setModel): Reimplemented. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JTextArea.java (append): Re-implemented. (insert): Likewise. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JSpinner.java (serialVersionUID): New static field. * javax/swing/JToggleButton.java (JToggleButton): Fixed email addresses. * javax/swing/SpinnerNumberModel.java (serialVersionUID): Added javadoc. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JTextArea.java: Don't use JTextComponent.doc directly. GCJ from java-gui-branch has a bug here which is fixed in HEAD ... 2004-11-30 Andrew John Hughes <address@hidden> * javax/swing/JTextArea.java: Added additional documentation. 2004-11-30 Andrew John Hughes <address@hidden> * javax/swing/JRadioButton.java: Implemented additional constructors and accessibility classes. Added documentation and fixed a typo in AbstractButton. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/IndexColorModel.java (IndexColorModel): Implement missing constructor. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/ComponentColorModel.java (ComponentColorModel): Implement missing 1.4 constructor. 2004-11-30 Andrew John Hughes <address@hidden> * javax/swing/JToggleButton.java: Implemented additional constructors and accessibility classes. Added documentation and fixed a typo in AbstractButton. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/ColorModel.java (getDataElement, getDataElements): Document since 1.4. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/BandedSampleModel.java: Implement. * Makefile.am: Add java/awt/image/BandedSampleModel.java. * Makefile.in: Regenerated. 2004-11-30 Michael Koch <konqueror@gmx.de> * java/awt/Window.java: Fixed whitespace difference with GNU classpath. 2004-11-30 Mark Wielaard <mark@klomp.org> * Makefile.am: Add javax/swing/SpinnerListModel.java. * Makefile.in: Regenerated. 2004-11-30 Andrew John Hughes <gnu_andrew@member.fsf.org> * javax/swing/SpinnerListModel.java, javax/swing/SpinnerModel.java Implemented SpinnerListModel. Added documentation to SpinnerModel. 2004-11-30 Andreas Tobler <a.tobler@schweiz.ch> * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMainThread.c (init_dpi_conversion_factor): Apply the patch from main correctly. 2004-06-26 Andreas Tobler <a.tobler@schweiz.ch> 2004-11-30 Tom Tromey <tromey@redhat.com> Bug 9948. * javax/swing/JDesktopPane.java (LIVE_DRAG_MODE): Now final. (OUTLINE_DRAG_MODE): LIVE_DRAG_MODE. * javax/swing/plaf/basic/BasicSplitPaneUI.java (NON_CONTINUOUS_DIVIDER): Now final. Initialize. 2004-11-30 Andrew John Hughes <gnu_andrew@member.fsf.org> * java/awt/Canvas.java (AccessibleAWTCanvas): added serialization UID * java/awt/Label.java (AccessibleAWTLabel): added serialization UID * javax/swing/JRootPane.java (AccessibleJRootPane): added comment to existing UID * javax/swing/JSpinner.java (DefaultEditor): added serialization UID (NumberEditor): added serialization UID * javax/swing/text/html/HTML.java (UnknownTag): added serialization UID 2004-11-30 Jeroen Frijters <jeroen@frijters.net> * javax/swing/JInternalFrame.java (CONTENT_PANE_PROPERTY,FRAME_ICON_PROPERTY,GLASS_PANE_PROPERTY, IS_CLOSED_PROPERTY,IS_ICON_PROPERTY,IS_MAXIMUM_PROPERTY, IS_SELECTED_PROPERTY,LAYERED_PANE_PROPERTY,MENU_BAR_PROPERTY, ROOT_PANE_PROPERTY,TITLE_PROPERTY): Made final as per API spec. * javax/swing/plaf/basic/BasicInternalFrameTitlePane.java (CLOSE_CMD,ICONIFY_CMD,MAXIMIZE_CMD,MOVE_CMD,RESTORE_CMD,SIZE_CMD): Made final as per API spec. 2004-11-30 Andreas Tobler <a.tobler@schweiz.ch> * jni/gtk-peer/gtkpeer.h: Remove duplicated copyright string. 2004-11-30 Sven de Marothy <sven@physto.se> * java/awt/geom/Arc2D.java: Reformatted. (setArc): Correct documentation to say 'upper left corner'. (setArcByTangent,contains,intersects): Implemented. (containsAngle): Corrected to handle negative extents. (ArcIterator): Set to private. (ArcIterator): Corrected for CHORD-type arcs, negative extents. (intersects): Fix: Now checks the arc segment. (contains): Cleaned up. * java/awt/geom/CubicCurve2a.javaD: Fix insideness-test. Reindent. (contains): Implemented. (intersects): Implemented. * java/awt/geom/QuadCurve2D.java: Fix insideness-test. Reindent. * java/awt/geom/GeneralPath: Fix insideness-test. Reindent and document. Fully (re)implemented using separate xpoints and ypoints float[] coords. 2004-11-30 Andreas Tobler <a.tobler@schweiz.ch> * configure.ac: Introduce AC_C_BIGENDIAN_CROSS for WORDS_BIGENDIAN. * configure: Regenerate. * include/config.h.in: Likewise. * jni/gtk-peer/gtkpeer.h (SWAPU32): Introduce macro to swap pixels. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImagePainter.c: Moved SWAPU32 macro to gtkpeer.h. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c (Java_gnu_java_awt_peer_gtk_GdkGraphics2D_getImagePixels): Convert pixels from 0xBBGGRRAA to 0xAARRGGBB only on Little Endian architectures. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkPixbufDecoder.c (area_updated): Likewise. 2004-11-30 David Gilbert <david.gilbert@object-refinery.com> * java/awt/SystemColor.java: Fix @link doc entries. 2004-11-30 David Gilbert <david.gilbert@object-refinery.com> * java/awt/RenderingHints.java: Documented. (RenderingHints): Accept null init Map. (putAll): Preprocess map to generate appropriate exceptions. (remove): Cast object to Key and remove from hintMap. 2004-11-30 Andrew John Hughes <gnu_andrew@member.fsf.org> * java/awt/MenuComponent.java, java/awt/MenuBar.java: Implementation of accessibility classes and methods for these two components. 2004-11-30 Andrew John Hughes <gnu_andrew@member.fsf.org> * java/awt/KeyboardFocusManager.java: Added missing documentation. 2004-11-30 Andrew John Hughes <gnu_andrew@member.fsf.org> * java/awt/Label.java, java/awt/Canvas.java: Added accessibility classes to AWT Label and Canvas, as well as additional documentation for Canvas. 2004-11-30 David Gilbert <address@bogus.example.com> * java/awt/image/DataBuffer.java: Update API documentation. * java/awt/image/DataBufferByte.java: Likewise. * java/awt/image/DataBufferDouble.java: Likewise. * java/awt/image/DataBufferFloat.java: Likewise. * java/awt/image/DataBufferInt.java: Likewise. * java/awt/image/DataBufferShort.java: Likewise. * java/awt/image/DataBufferUShort.java: Likewise. 2004-11-30 Dalibor Topic <robilad@kaffe.org> * java/awt/Component.java (postEvent): Only delegate to parent if a parent exists. Reported by: Stephane Meslin-Weber <steph@tangency.co.uk> 2004-11-30 Sven de Marothy <sven@physto.se> *java/awt/AWTEventMulticaster.java, java/awt/Adjustable.java, java/awt/Point.java, java/awt/Polygon.java, java/awt/Rectangle.java, java/awt/Shape.java, java/awt/geom/Area.java, java/awt/geom/Ellipse2D.java, java/awt/geom/PathIterator.java, java/awt/geom/Point2D.java, java/awt/geom/Rectangle2D.java, java/lang/Comparable.java, java/util/Arrays.java: Fixed documentation errors 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/ComponentSampleModel.java: Add documentation. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/ComponentSampleModel.java (constructor): Initialize numBanks when figuring out the max bank index. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/Raster.java (createPackedRaster): Implement MultiPixelPackedSampleModel codepath. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/MultiPixelPackedSampleModel.java: Implement. * Makefile.am: Add MultiPixelPackedSampleModel.java. * Makefile.in: Regenerate. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/Raster.java (getNumBands): Implement. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/Raster.java (createPackedRaster(int,int,int,int,int,Point)): Implement for bands>1. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/SinglePixelPackedSampleModel.java (SinglePixelPackedSampleModel): Throw exception for unsupported datatype. 2004-11-30 Jerry Quinn <jlquinn@optonline.net> * java/awt/image/ColorModel.java (getDataElement): Implemented. Update javadoc. (getDataElements): Add missing version. Remove bogus version. Update javadoc. 2004-11-30 Olga Rodimina <rodimina@redhat.com> * javax/swing/plaf/basic/BasicComboBoxUI.java: (paintCurrentValue): Pass correct parameters to getListCellRendererComponent(). (ListDataHandler.intervalRemoved): Implemented. (PropertyChangeHandler.propertyChange): Handle changes in MODEL_CHANGED_PROPERTY of the JComboBox * javax/swing/plaf/basic/BasicComboPopup.java: (BasicComboPopup): Moved code that configures popup to configurePopup() and call it instead. (firePopupMenuWillBecomeVisible): Implemented. (firePopupMenuWillBecomeInvisible): Likewise. (firePopupMenuCanceled): Likewise. (configureList): Set list's visibleRowCount same as comboBox's visibleRowCount. (configurePopup): Implemented. (getPopupHeightForRowCount): Get item's from JComboBox's model and not from model of the JList. (ListMouseMotionHandler.mouseMoved): Implemented. (PropertyChangeHandler.propertyChange): Handles change in the JComboBox's model. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JComponent.java (isMaximumSizeSet): New method. (isMinimumSizeSet): Likewise. (isPreferredSizeSet): Likewise. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JSpinner.java: Some Re-formatting. (spinner): New field. (DefaultEditor): New method. (getSpinner): Likewise. (NumberEdito): Likewise. (getModel): Likewise 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/InputVerifier.java: Re-formatted. * javax/swing/JComponent.java (inputVerifier): New property field. (getInputVerifier): New method. (setInputVerifier): Likewise. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JComponent.java (JComponent): Added javadoc comment. (setBorder): Fire property change eventr. (setEnabled): Likewise. (setMaximumSize): Likewise. (setMinimumSize): Likewise. (setPreferredSize): Likewise. (setOpaque): Likewise. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JTextField.java (action): New field. (actionCommand): Likewise. (actionPropertyChangeListener): Likewise. (setHorizontalAlignment): Abort soon if new value == old value. Fire event before repainting. (postActionEvent): New method. (getAction): Likewise. (setAction): Likewise. (getActionCommand): Likewise. (setActionCommand): Likewise. (createActionPropertyChangeListener): Likewise. (configurePropertiesFromAction): Likewise. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/DebugGraphics.java: Re-formatted. Fixed some javadocs. * javax/swing/JApplet.java (rootPaneCheckingEnabled): Renamed from checking. * javax/swing/JCheckBox.java (BORDER_PAINTED_FLAT_CHANGED_PROPERTY): New statif field. * javax/swing/JFrame.java: Re-formatted a bit and reordered some methods. (rootPaneCheckingEnabled): Renamed from checking. (getPreferredSize): Simplified. * javax/swing/JTextArea.java (getColumnWidth): New method. (getLineCount): Likewise. (getLineStartOffset): Likewise. (getLineEndOffset): Likewise. (getLineOfOffset): Likewise. (getRowHeight): Likewise. (insert): Likewise. (replaceRange): Likewise. * javax/swing/JTextField.java (scrollOffset): new field. (getScrollOffset): New method. (setScrollOffset): Likewise. (getColumnWidth): Likewise. * javax/swing/JTree.java (ANCHOR_SELECTION_PATH_PROPERTY): New static field. (CELL_EDITOR_PROPERTY): Likewise. (CELL_RENDERER_PROPERTY): Likewise. (EDITABLE_PROPERTY): Likewise. (EXPANDS_SELECTED_PATHS_PROPERTY): Likewise. (INVOKES_STOP_CELL_EDITING_PROPERTY): Likewise. (LARGE_MODEL_PROPERTY): Likewise. (LEAD_SELECTION_PATH_PROPERTY): Likewise. (ROOT_VISIBLE_PROPERTY): Likewise. (ROW_HEIGHT_PROPERTY): Likewise. (SCROLLS_ON_EXPAND_PROPERTY): Likewise. (SELECTION_MODEL_PROPERTY): Likewise. (SHOWS_ROOT_HANDLES_PROPERTY): Likewise. (TOGGLE_CLICK_COUNT_PROPERTY): Likewise. (TREE_MODEL_PROPERTY): Likewise. (VISIBLE_ROW_COUNT_PROPERTY): Likewise. (cellEditor): New field. (invokesStopCellEditing): Likewise. (largeModel): Likewise. (rowHeight): Likewise. (scrollsOnExpand): Likewise. (selectionModel): Likewise. (toggleClickCount): Likewise. (visibleRowCount): Likewise. (setShowsRootHandles): Fixed typo in method name. (getCellEditor): New method. (setCellEditor): Likewise. (getSelectionModel): Likewise. (setSelectionModel): Likewise. (getVisibleRowCount): Likewise. (setVisibleRowCount): Likewise. (isLargeModel): Likewise. (setLargeModel): Likewise. (getRowHeight): Likewise. (setRowHeight): Likewise. (getInvokesStopCellEditing): Likewise. (setInvokesStopCellEditing): Likewise. (getToggleClickCount): Likewise. (setToggleClickCount): Likewise. (getScrollsOnExpand): Likewise. (setScrollsOnExpand): Likewise. * javax/swing/table/DefaultTableColumnModel.java (addColumnModelListener): Fixed javadoc. (removeColumnModelListener): Implemented. Fixed javadoc. (getColumnModelListeners): New method. * javax/swing/table/JTableHeader.java (columnModel): Made protected. (draggedColumn): Likewise. (draggedDistance): Likewise. (reorderingAllowed): Likewise. (resizingAllowed): Likewise. (resizingColumn): Likewise. (table): Likewise. (updateTableInRealTime): Likewise. (createDefaultColumnModel): Renamed from createDefaultTableColumnModel. (setDefaultRenderer): New method. * javax/swing/table/TableColumn.java (getPropertyChangeListeners): New method. * javax/swing/text/DefaultHighlighter.java (drawsLayeredHighlights): New field. (getDrawsLayeredHighlights): New method. (setDrawsLayeredHighlights): Likewise. * javax/swing/text/DocumentFilter.java (FilterBypass): New inner class. (insertString): New method. (remove): Likewise. (replace): Likewise. * javax/swing/text/JTextComponent.java (dragEnabled): New field. (getSelectedText): New method. (getDragEnabled): Likewise. (setDragEnabled): Likewise. (replaceSelection): Reimplemented. * javax/swing/text/NavigationFilter.java (FilterBypass): New inner class. (NavigationFilter): New method. (moveDot): Likewise. (setDot): Likewise. * javax/swing/text/SimpleAttributeSet.java (EMPTY): Made public final. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/SpinnerNumberModel.java (getMinimum): New method. (setMinimum): Likewise. (getMaximum): Likewise. (setMaximum): Likewise. (getStepSize): Likewise. (setStepSize): Likewise. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JMenu.java (getMenuListeners): New method. (fireMenuSelected): Simplified. * javax/swing/JRootPane.java (NONE): New static field. (FRAME): Likewise. (PLAIN_DIALOG): Likewise. (INFORMATION_DIALOG): Likewise. (ERROR_DIALOG): Likewise. (COLOR_CHOOSER_DIALOG): Likewise. (FILE_CHOOSER_DIALOG): Likewise. (QUESTION_DIALOG): Likewise. (WARNING_DIALOG): Likewise. (defaultButton): New field. (getDefaultButton): New method. (setDefaultButton): Likewise. * javax/swing/JScrollPane.java (getUI): New method. (setUI): Likewise. * javax/swing/JTable.java (getUI): Javadoc added. (setUI): New method. * javax/swing/JViewport.java (getUI): New method. (setUI): Likewise. * javax/swing/UIDefaults.java (removePropertyChangeListener): Made public. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JApplet.java, javax/swing/JFrame.java: Re-indented. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/AbstractButton.java: Little re-formatting. (changeEvent): Made protected. (fireStateChanged): Removed argument. (setHorizontalAlignment): Abort method when old value is equal too new value. (setHorizontalTextPosition): Likewise. (setVerticalAlignment): Likewise. (setVerticalTextPosition): Likewise. (setBorderPainted): Likewise. (setIcon): Likewise. (setText): Likewise. (setIconTextGap): Likewise. (setMargin): Likewise. (setPressedIcon): Likewise. (setFocusPainted): Likewise. (setDisabledSelectedIcon): Likewise. (setRolloverIcon): Likewise. (setRolloverSelectedIcon): Likewise. (setSelectedIcon): Likewise. (setContentAreaFilled): Likewise. 2004-11-30 Kim Ho <kho@redhat.com> * javax/swing/plaf/basic/BasicArrowButton.java: Jalopy. Reimplement. * javax/swing/plaf/basic/BasicScrollBarUI.java: Jalopy. (arrowIcon, upIcon, downIcon, leftIcon, rightIcon): Removed. (createIncreaseButton): Use BasicArrowButton. (createDecreaseButton): Ditto. * javax/swing/plaf/basic/BasicSplitPaneDivider.java: (createRightOneTouchButton): Remove button border. (createLeftOneTouchButton): Ditto. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JSpinner.java (setModel): New method. * javax/swing/SpringLayout.java (Constraints): May not be final. 2004-11-30 Michael Koch <konqueror@gmx.de> * gnu/java/awt/peer/gtk/GtkClipboard.java, java/awt/datatransfer/Clipboard.java, java/awt/datatransfer/ClipboardOwner.java: Reformated to make it use our coding standard. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/SpinnerNumberModel.java (SpinnerNumberModel): Implements java.io.Serializable. (serialVersionUID): New field. (SpinnerNumberModel): Added missing @throws tags to javadocs. * javax/swing/UIManager.java (get): New method. (getBoolean): Likewise. (getBorder): Likewise. (getColor): Likewise. (getDimension): Likewise. (getFont): Likewise. (getIcon): Likewise. (getInsets): Likewise. (getInt): Likewise. (getString): Likewise. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JPasswordField.java: Reformated. Implemented construtors. * javax/swing/plaf/basic/BasicPasswordFieldUI.java (create): New method. * javax/swing/text/PlainView.java (selectedColor): Made package-private to allow access from sub-classes in same package too. (unselectedColor): Likewise. (font): Likewise. (drawSelectedText): Make protected. (drawUnselectedText): Likewise. * javax/swing/text/PasswordView.java: New file. * Makefile.am: Added javax/swing/text/PasswordView.java. * Makefile.in: Regenerated. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * gnu/java/awt/peer/gtk/GtkFramePeer.java (setMenuBar): Set menu bar's width. * gnu/java/awt/peer/gtk/GtkMenuBarPeer.java (nativeSetHelpMenu): Add FIXME comment. (addHelpMenu): Elide call to nativeSetHelpMenu. * java/awt/Menu.java (isTearOff): Rename to tearOff. (menuSerializedDataVersion): Initialize to 1. (separatorLabel): Mark transient. (insert(MenuItem,int)): Implement. * java/awt/MenuBar.java (setHelpMenu): Call getPeer to retrieve peer. (countMenus): Count help menu. * java/awt/MenuComponent.java (nameExplicitlySet, newEventsOnly, accessibleContext): Add fields. * java/awt/MenuItem.java: Remove event mask FIXME. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c (gtkWidgetModifyFont): Only set font if label is non-NULL. (setLabel): Don't treat "-" specially. 2004-11-30 Kim Ho <kho@redhat.com> * javax/swing/colorchooser/DefaultHSBChooserPanel.java: (stateChanged): Only update the image and the track if the values are not being adjusted. (updateChooser): Grab the new mouse point from the spinner values. Update the image and track only if the values are not being adjusted. (getHSBValues): New method. * javax/swing/colorchooser/DefaultRGBChooserPanel.java: (SliderHandler::stateChanged): Changed internalChange to updateChange. Set sliderChange. (SpinnerHandler::stateChanged): Ditto. Set spinnerChange. (spinnerChange): New variable. (sliderChange): Ditto. (updateChange): Renamed from internalChange. (updateChooser): Do not update sliders if the sliders were the original source of the change. Ditto for spinners. * javax/swing/plaf/basic/BasicTabbedPaneUI.java: (mousePress): Don't scroll the JViewport if there will be extra space at the end of the run. Change layout() to revalidate(). (calculateSize): Use the component's width/height unless it is smaller than the max tab width/height. (calculateTabRects): Subtract the tab run overlay. (rotateTabRuns): Don't rotate if there's only one run. (layoutContainer): Reuse the viewport point. (createLayoutManager): Set the viewport to use no layout. (paintTabArea): Don't paint the tabs that are not visible to the JViewport. (paintContentBorderTopEdge): Check for scroll tab layout before looking for gap. (paintContentBorderLeftEdge): Ditto. (paintContentBorderBottomEdge): Ditto. (paintContentBorderRightEdge): Ditto. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * gnu/java/awt/peer/gtk/GtkButtonPeer.java (gtkWidgetSetFont): Rename ... (gtkWidgetModifyFont): New method. * gnu/java/awt/peer/gtk/GtkFramePeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c (setMenuBarWidth): New method. (setBounds): Set the menu bar width. (postConfigureEvent): Set the menu bar width if the window's width has changed. * gnu/java/awt/peer/gtk/GtkMenuBarPeer.java (GtkMenuBarPeer): Don't call create. (setFont): New method. * gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java (create): New method. (setFont): Likewise. (GtkMenuComponentPeer): Call create and setFont. * gnu/java/awt/peer/gtk/GtkMenuItemPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkMenuItemPeer.c (connectSignals): Make package private. (gtkWidgetModifyFont): New method. (create): Likewise. (GtkMenuItemPeer): Don't call create. (setFont): New method. * java/awt/CheckboxMenuItem.java (addNotify): Fix peer == null condition. * java/awt/Container.java (validateTree): Fix comment typos. * java/awt/MenuComponent.java (getFont): Return parent's font if our font is null. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c (create): Remove call to deprecated gtk_check_menu_item_set_show_toggle function. 2004-11-30 Hans Boehm <Hans.Boehm@hp.com> * java/lang/natObject.cc (LOCK_LOG, LOG): Add debug tracing. (Almost everywhere): add LOG calls, fix, add comments. (_Jv_MonitorEnter): Replace masking of LOCKED bit with assertion. Add explicit check for LOCKED bit in slow case (PR 16662). (_Jv_MonitorExit): Add casts in debug-only code. Always release LOCKED bit before throwing exception. (_Jv_ObjectCheckMonitor): Lock may be held if lightweight lock isn't. Handle easy cases without lock acquisition. (Object::wait): Use NotifyAll for lock inflation. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * gnu/java/awt/peer/gtk/GtkFramePeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c (gtkFixedMove): Remove method. 2004-11-30 Sven de Marothy <sven@physto.se> * java/awt/geom/Area.java: Implemented. 2004-11-30 Mark Wielaard <mark@klomp.org> * java/awt/geom/Arc2D.java (ArcIterator): Make package private. 2004-11-30 Sven de Marothy <sven@physto.se> * java/awt/geom/Arc2D.java Reformatted. (setArc): Correct documentation to say 'upper left corner'. (setArcByTangent,contains,intersects): Implemented. (containsAngle): Corrected to handle negative extents. (ArcIterator): Set to private. (ArcIterator): Corrected for CHORD-type arcs, negative extents. * java/awt/geom/Ellipse2D.java Documented. (contains,intersects): Implemented. * java/awt/geom/Line2D.java (linesIntersect): Correct handling of special cases. 2004-11-30 Mark Wielaard <mark@klomp.org> * gnu/java/awt/peer/gtk/GdkGraphics.java (setColor): Use Color.BLACK if c == null, don't create new Color object each time. * gnu/java/awt/peer/gtk/GdkGraphics2D.java (comp): New private field. (setColor): Use Color.BLACK when argument null. (setComposite): Set this.comp field. (getComposite): Return this.comp, or AlphaComposite.SrcOver when null. (DrawState.comp): New private field. (DrawState.save): Save Composite. (DrawState.restore): Restore comp field. * java/awt/FontMetrics.java (gRC): New static final private field. (getLineMetrics(String, Graphics)): New method. (getLineMetrics(String, int, int, Graphics)): Likewise. (getLineMetrics(char[], int, int, Graphics)): Likewise. (getLineMetrics(CharacterIterator, int, int, Graphics)): Likewise. * javax/swing/JMenu.java (JMenu(String, boolean)): Ignore tearoff argument. PR SWING/17294. * javax/swing/plaf/basic/BasicGraphicsUtils.java (): Always use the fall-back code since none of the TextArea methods are really implemented now. PR SWING/17296. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c (GdkGlyphVector_setChars): Replace assert() with if block when pango_itemize() returns null. PR AWT/17295. (GdkGlyphVector_allInkExtents): Likewise when vec->glyphitems is null. 2004-11-30 Thomas Fitzsimmons <fitzsim@redhat.com> * Makefile.am (gtk_c_source_files): Add gnu_java_awt_peer_gtk_GtkFramePeer.c. * Makefile.in: Regenerate. * gnu/java/awt/peer/gtk/GdkGraphics.java (getClipBounds): Remove comment. * gnu/java/awt/peer/gtk/GtkButtonPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkButtonPeer.c (create): Pack GtkButton in GtkEventBox. (connectJObject): Remove. (focus_in_cb): New function. (focus_out_cb): Likewise. (connectSignals): Connect focus-in-event and focus-out-event signals. (gtkSetFont): Rename to ... (gtkWidgetModifyFont): New method. (gtkWidgetRequestFocus): New method. * gnu/java/awt/peer/gtk/GtkCheckboxPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCheckboxPeer.c (gtkSetFont): Rename to ... (gtkWidgetModifyFont): New method. * gnu/java/awt/peer/gtk/GtkComponentPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c (isInRepaint): New field. (gtkSetFont): Remove method. (addExposeFilter): Likewise. (removeExposeFilter): Likewise. (gtkWidgetQueueDrawArea): Rename to ... (gtkWidgetRepaintArea): New method. (beginNativeRepaint): New method. (endNativeRepaint): New method. (setComponentBounds): Move implementation here from GtkComponentPeer. (paint): Remove implementation. (repaint): Wrap call to gtkWidgetRepaintArea with calls to beginNativeRepaint and endNativeRepaint. (setBounds): Use menu bar height in bounds calculation. (postExposeEvent): Only post paint event if we're not doing a native repaint. (gtkWidgetSetParent): Replace gtk_layout_put with gtk_fixed_put. (setNativeBounds): Replace gtk_layout_move with gtk_fixed_move. (find_gtk_layout): Remove function. (filter_expose_event_handler): Likewise. * gnu/java/awt/peer/gtk/GtkDialogPeer.java (postExposeEvent): Likewise. * gnu/java/awt/peer/gtk/GtkFileDialogPeer.java (setComponentBounds): Call GtkComponentPeer's setComponentBounds. * gnu/java/awt/peer/gtk/GtkFramePeer.java (getMenuBarHeight): New method. (moveLayout): Rename to ... (gtkFixedMove): New method. (gtkLayoutSetVisible): Rename to ... (gtkFixedSetVisible): New method. (setMenuBar): Rearrange, to make the three separate cases clearer. (postExposeEvent): Only post paint event if we're not doing a native repaint. * gnu/java/awt/peer/gtk/GtkGenericPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkGenericPeer.c (gtkWidgetModifyFont): New method. * gnu/java/awt/peer/gtk/GtkImagePainter.java (GtkImagePainter(GtkImage,GdkGraphics,int,int,int,int,Color)): Call run directly, rather than spawning a new thread. (GtkImagePainter(GtkImage,GdkGraphics,int,int,int,int,int,int,int,int,Color)): Likewise. * gnu/java/awt/peer/gtk/GtkLabelPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkLabelPeer.c (gtkSetFont): Rename to ... (gtkWidgetModifyFont): New method. (create): Rename ebox to eventbox. * gnu/java/awt/peer/gtk/GtkListPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkListPeer.c (gtkSetFont): Rename to ... (gtkWidgetModifyFont): New method. * gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java (GtkMenuComponentPeer): Set the default font. * gnu/java/awt/peer/gtk/GtkTextAreaPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextAreaPeer.c (gtkSetFont): Rename to ... (gtkWidgetModifyFont): New method. * gnu/java/awt/peer/gtk/GtkTextFieldPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c: Likewise. * java/awt/Component.java (locale): Initialize to default locale. * java/awt/Container.java (invalidateTree): Make package-private. (paint): Paint self first. (setMenuBar): Call invalidateTree. * java/awt/Panel.java (dispatchEventImpl): Remove method. * java/awt/Window.java (show): Call no-parameter variant of requestFocusInWindow. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics.c (initState): Remove special case for window widget. * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c (grab_current_drawable): Likewise. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c (create): Replace GtkLayout with GtkFixed. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkEvents.c (pre_event_handler): Remove special cases for GDK_EXPOSE events. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c: New file. Move all GtkFramePeer native method implementations here from gnu_java_awt_peer_gtk_GtkWindowPeer.c. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkPanelPeer.c (create): Replace GtkLayout with GtkFixed. * jni/gtk-peer/gnu_java_awt_peer_gtk_GtkWindowPeer.c (find_layout): Remove function. (create): Replace GtkLayout with GtkFixed. (connectSignals): Remove find_layout call. (toBack): Replace XFlush with gdk_flush. (toFront): Replace XFlush with gdk_flush. Move GtkFramePeer native method implementations to gnu_java_awt_peer_gtk_GtkFramePeer.c. * jni/gtk-peer/gtkpeer.h: Remove declaration of find_gtk_layout. 2004-11-30 Michael Koch <konqueror@gmx.de> * javax/swing/JTextArea.java (lineWrap): Renamed from "wrapping". (wrapStyleWord): NEw field. (getLineWrap): Re-edited javadoc comment. (setLineWrap): Likewise. (getWrapStyleWord): New method. (setWrapStyleWord): Likewise. From-SVN: r91544
Diffstat (limited to 'libjava/java')
-rw-r--r--libjava/java/applet/Applet.java17
-rw-r--r--libjava/java/awt/AWTEventMulticaster.java76
-rw-r--r--libjava/java/awt/AWTKeyStroke.java4
-rw-r--r--libjava/java/awt/Adjustable.java4
-rw-r--r--libjava/java/awt/BasicStroke.java4
-rw-r--r--libjava/java/awt/Button.java128
-rw-r--r--libjava/java/awt/Canvas.java141
-rw-r--r--libjava/java/awt/CardLayout.java128
-rw-r--r--libjava/java/awt/Checkbox.java107
-rw-r--r--libjava/java/awt/CheckboxMenuItem.java14
-rw-r--r--libjava/java/awt/Choice.java69
-rw-r--r--libjava/java/awt/Component.java207
-rw-r--r--libjava/java/awt/Container.java79
-rw-r--r--libjava/java/awt/DefaultKeyboardFocusManager.java41
-rw-r--r--libjava/java/awt/EventDispatchThread.java15
-rw-r--r--libjava/java/awt/EventQueue.java2
-rw-r--r--libjava/java/awt/FileDialog.java5
-rw-r--r--libjava/java/awt/FlowLayout.java13
-rw-r--r--libjava/java/awt/Font.java82
-rw-r--r--libjava/java/awt/FontMetrics.java111
-rw-r--r--libjava/java/awt/Frame.java6
-rw-r--r--libjava/java/awt/Graphics.java14
-rw-r--r--libjava/java/awt/Graphics2D.java7
-rw-r--r--libjava/java/awt/GraphicsEnvironment.java7
-rw-r--r--libjava/java/awt/GridBagConstraints.java11
-rw-r--r--libjava/java/awt/GridBagLayout.java4
-rw-r--r--libjava/java/awt/GridLayout.java7
-rw-r--r--libjava/java/awt/Image.java3
-rw-r--r--libjava/java/awt/KeyboardFocusManager.java561
-rw-r--r--libjava/java/awt/Label.java70
-rw-r--r--libjava/java/awt/LayoutManager2.java4
-rw-r--r--libjava/java/awt/List.java7
-rw-r--r--libjava/java/awt/MediaTracker.java4
-rw-r--r--libjava/java/awt/Menu.java77
-rw-r--r--libjava/java/awt/MenuBar.java78
-rw-r--r--libjava/java/awt/MenuComponent.java1053
-rw-r--r--libjava/java/awt/MenuItem.java113
-rw-r--r--libjava/java/awt/Panel.java39
-rw-r--r--libjava/java/awt/Point.java2
-rw-r--r--libjava/java/awt/Polygon.java514
-rw-r--r--libjava/java/awt/PopupMenu.java24
-rw-r--r--libjava/java/awt/Rectangle.java2
-rw-r--r--libjava/java/awt/RenderingHints.java439
-rw-r--r--libjava/java/awt/ScrollPane.java3
-rw-r--r--libjava/java/awt/Scrollbar.java10
-rw-r--r--libjava/java/awt/Shape.java26
-rw-r--r--libjava/java/awt/SystemColor.java58
-rw-r--r--libjava/java/awt/TextArea.java91
-rw-r--r--libjava/java/awt/TextComponent.java248
-rw-r--r--libjava/java/awt/TextField.java25
-rw-r--r--libjava/java/awt/Toolkit.java10
-rw-r--r--libjava/java/awt/Window.java15
-rw-r--r--libjava/java/awt/color/ICC_ColorSpace.java167
-rw-r--r--libjava/java/awt/color/ICC_Profile.java1173
-rw-r--r--libjava/java/awt/color/ICC_ProfileGray.java76
-rw-r--r--libjava/java/awt/color/ICC_ProfileRGB.java163
-rw-r--r--libjava/java/awt/datatransfer/Clipboard.java162
-rw-r--r--libjava/java/awt/datatransfer/ClipboardOwner.java3
-rw-r--r--libjava/java/awt/datatransfer/DataFlavor.java11
-rw-r--r--libjava/java/awt/datatransfer/FlavorTable.java4
-rw-r--r--libjava/java/awt/datatransfer/StringSelection.java33
-rw-r--r--libjava/java/awt/datatransfer/SystemFlavorMap.java4
-rw-r--r--libjava/java/awt/dnd/Autoscroll.java5
-rw-r--r--libjava/java/awt/dnd/DropTarget.java5
-rw-r--r--libjava/java/awt/dnd/DropTargetContext.java7
-rw-r--r--libjava/java/awt/dnd/DropTargetDragEvent.java5
-rw-r--r--libjava/java/awt/dnd/peer/DropTargetContextPeer.java5
-rw-r--r--libjava/java/awt/event/ActionListener.java6
-rw-r--r--libjava/java/awt/event/AdjustmentEvent.java4
-rw-r--r--libjava/java/awt/event/HierarchyBoundsAdapter.java6
-rw-r--r--libjava/java/awt/event/InputEvent.java6
-rw-r--r--libjava/java/awt/event/InvocationEvent.java4
-rw-r--r--libjava/java/awt/event/KeyEvent.java5
-rw-r--r--libjava/java/awt/event/MouseEvent.java5
-rw-r--r--libjava/java/awt/font/TextAttribute.java12
-rw-r--r--libjava/java/awt/font/TextLayout.java259
-rw-r--r--libjava/java/awt/geom/AffineTransform.java73
-rw-r--r--libjava/java/awt/geom/Arc2D.java415
-rw-r--r--libjava/java/awt/geom/Area.java3212
-rw-r--r--libjava/java/awt/geom/CubicCurve2D.java11
-rw-r--r--libjava/java/awt/geom/Ellipse2D.java225
-rw-r--r--libjava/java/awt/geom/GeneralPath.java105
-rw-r--r--libjava/java/awt/geom/Line2D.java117
-rw-r--r--libjava/java/awt/geom/PathIterator.java4
-rw-r--r--libjava/java/awt/geom/Point2D.java11
-rw-r--r--libjava/java/awt/geom/QuadCurve2D.java11
-rw-r--r--libjava/java/awt/geom/Rectangle2D.java32
-rw-r--r--libjava/java/awt/geom/RectangularShape.java2
-rw-r--r--libjava/java/awt/im/InputContext.java8
-rw-r--r--libjava/java/awt/im/spi/InputMethod.java2
-rw-r--r--libjava/java/awt/im/spi/InputMethodContext.java7
-rw-r--r--libjava/java/awt/image/AffineTransformOp.java159
-rw-r--r--libjava/java/awt/image/BandCombineOp.java168
-rw-r--r--libjava/java/awt/image/BandedSampleModel.java537
-rw-r--r--libjava/java/awt/image/BufferedImage.java26
-rw-r--r--libjava/java/awt/image/BufferedImageFilter.java110
-rw-r--r--libjava/java/awt/image/ByteLookupTable.java18
-rw-r--r--libjava/java/awt/image/ColorConvertOp.java319
-rw-r--r--libjava/java/awt/image/ColorModel.java120
-rw-r--r--libjava/java/awt/image/ComponentColorModel.java38
-rw-r--r--libjava/java/awt/image/ComponentSampleModel.java85
-rw-r--r--libjava/java/awt/image/ConvolveOp.java341
-rw-r--r--libjava/java/awt/image/CropImageFilter.java5
-rw-r--r--libjava/java/awt/image/DataBuffer.java231
-rw-r--r--libjava/java/awt/image/DataBufferByte.java115
-rw-r--r--libjava/java/awt/image/DataBufferDouble.java115
-rw-r--r--libjava/java/awt/image/DataBufferFloat.java115
-rw-r--r--libjava/java/awt/image/DataBufferInt.java118
-rw-r--r--libjava/java/awt/image/DataBufferShort.java118
-rw-r--r--libjava/java/awt/image/DataBufferUShort.java118
-rw-r--r--libjava/java/awt/image/DirectColorModel.java20
-rw-r--r--libjava/java/awt/image/IndexColorModel.java239
-rw-r--r--libjava/java/awt/image/LookupOp.java252
-rw-r--r--libjava/java/awt/image/MemoryImageSource.java60
-rw-r--r--libjava/java/awt/image/MultiPixelPackedSampleModel.java387
-rw-r--r--libjava/java/awt/image/PackedColorModel.java6
-rw-r--r--libjava/java/awt/image/PixelGrabber.java70
-rw-r--r--libjava/java/awt/image/RGBImageFilter.java25
-rw-r--r--libjava/java/awt/image/Raster.java86
-rw-r--r--libjava/java/awt/image/RasterOp.java5
-rw-r--r--libjava/java/awt/image/RescaleOp.java218
-rw-r--r--libjava/java/awt/image/SampleModel.java11
-rw-r--r--libjava/java/awt/image/ShortLookupTable.java12
-rw-r--r--libjava/java/awt/image/SinglePixelPackedSampleModel.java12
-rw-r--r--libjava/java/awt/print/Book.java14
-rw-r--r--libjava/java/awt/print/Printable.java84
-rw-r--r--libjava/java/awt/print/PrinterJob.java451
127 files changed, 13776 insertions, 2176 deletions
diff --git a/libjava/java/applet/Applet.java b/libjava/java/applet/Applet.java
index 4fbf17c11e3..a7609d9ab63 100644
--- a/libjava/java/applet/Applet.java
+++ b/libjava/java/applet/Applet.java
@@ -78,6 +78,12 @@ public class Applet extends Panel
/** The applet stub for this applet. */
private transient AppletStub stub;
+ /** Some applets call setSize in their constructors. In that case,
+ these fields are used to store width and height values until a
+ stub is set. */
+ private transient int width;
+ private transient int height;
+
/**
* The accessibility context for this applet.
*
@@ -107,6 +113,9 @@ public class Applet extends Panel
public final void setStub(AppletStub stub)
{
this.stub = stub;
+
+ if (width != 0 && height != 0)
+ stub.appletResize (width, height);
}
/**
@@ -174,7 +183,13 @@ public class Applet extends Panel
*/
public void resize(int width, int height)
{
- stub.appletResize(width, height);
+ if (stub == null)
+ {
+ this.width = width;
+ this.height = height;
+ }
+ else
+ stub.appletResize(width, height);
}
/**
diff --git a/libjava/java/awt/AWTEventMulticaster.java b/libjava/java/awt/AWTEventMulticaster.java
index 58950ef0b98..b26d1f35d05 100644
--- a/libjava/java/awt/AWTEventMulticaster.java
+++ b/libjava/java/awt/AWTEventMulticaster.java
@@ -181,7 +181,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void componentResized(ComponentEvent e)
{
@@ -193,7 +193,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void componentMoved(ComponentEvent e)
{
@@ -205,7 +205,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void componentShown(ComponentEvent e)
{
@@ -217,7 +217,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void componentHidden(ComponentEvent e)
{
@@ -229,7 +229,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void componentAdded(ContainerEvent e)
{
@@ -241,7 +241,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void componentRemoved(ContainerEvent e)
{
@@ -253,7 +253,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void focusGained(FocusEvent e)
{
@@ -265,7 +265,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void focusLost(FocusEvent e)
{
@@ -277,7 +277,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void keyTyped(KeyEvent e)
{
@@ -289,7 +289,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void keyPressed(KeyEvent e)
{
@@ -301,7 +301,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void keyReleased(KeyEvent e)
{
@@ -313,7 +313,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void mouseClicked(MouseEvent e)
{
@@ -325,7 +325,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void mousePressed(MouseEvent e)
{
@@ -337,7 +337,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void mouseReleased(MouseEvent e)
{
@@ -349,7 +349,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void mouseEntered(MouseEvent e)
{
@@ -361,7 +361,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void mouseExited(MouseEvent e)
{
@@ -373,7 +373,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void mouseDragged(MouseEvent e)
{
@@ -385,7 +385,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void mouseMoved(MouseEvent e)
{
@@ -397,7 +397,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void windowOpened(WindowEvent e)
{
@@ -409,7 +409,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void windowClosing(WindowEvent e)
{
@@ -421,7 +421,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void windowClosed(WindowEvent e)
{
@@ -433,7 +433,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void windowIconified(WindowEvent e)
{
@@ -445,7 +445,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void windowDeiconified(WindowEvent e)
{
@@ -457,7 +457,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void windowActivated(WindowEvent e)
{
@@ -469,7 +469,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void windowDeactivated(WindowEvent e)
{
@@ -481,7 +481,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
* @since 1.4
*/
public void windowStateChanged(WindowEvent e)
@@ -494,7 +494,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
* @since 1.4
*/
public void windowGainedFocus(WindowEvent e)
@@ -507,7 +507,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
* @since 1.4
*/
public void windowLostFocus(WindowEvent e)
@@ -520,7 +520,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void actionPerformed(ActionEvent e)
{
@@ -532,7 +532,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void itemStateChanged(ItemEvent e)
{
@@ -544,7 +544,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void adjustmentValueChanged(AdjustmentEvent e)
{
@@ -556,7 +556,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
*/
public void textValueChanged(TextEvent e)
{
@@ -568,7 +568,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
* @since 1.2
*/
public void inputMethodTextChanged(InputMethodEvent e)
@@ -581,7 +581,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
* @since 1.2
*/
public void caretPositionChanged(InputMethodEvent e)
@@ -594,7 +594,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
* @since 1.3
*/
public void hierarchyChanged(HierarchyEvent e)
@@ -607,7 +607,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
* @since 1.3
*/
public void ancestorMoved(HierarchyEvent e)
@@ -620,7 +620,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
* @since 1.3
*/
public void ancestorResized(HierarchyEvent e)
@@ -633,7 +633,7 @@ public class AWTEventMulticaster
* Handles this event by dispatching it to the "a" and "b" listener
* instances.
*
- * @param event the event to handle
+ * @param e the event to handle
* @since 1.4
*/
public void mouseWheelMoved(MouseWheelEvent e)
diff --git a/libjava/java/awt/AWTKeyStroke.java b/libjava/java/awt/AWTKeyStroke.java
index 23ae92bf098..53e64b7fb1b 100644
--- a/libjava/java/awt/AWTKeyStroke.java
+++ b/libjava/java/awt/AWTKeyStroke.java
@@ -1,5 +1,5 @@
/* AWTKeyStroke.java -- an immutable key stroke
- Copyright (C) 2002 Free Software Foundation
+ Copyright (C) 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -48,9 +48,9 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import java.util.Map;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.StringTokenizer;
/**
diff --git a/libjava/java/awt/Adjustable.java b/libjava/java/awt/Adjustable.java
index 58116e4e5b3..815c77ca936 100644
--- a/libjava/java/awt/Adjustable.java
+++ b/libjava/java/awt/Adjustable.java
@@ -157,7 +157,7 @@ public interface Adjustable
* Adds a listener that will receive adjustment events for this object.
*
* @param listener the adjustment listener to add
- * @see AdjustmentEvent
+ * @see java.awt.event.AdjustmentEvent
*/
void addAdjustmentListener(AdjustmentListener listener);
@@ -165,7 +165,7 @@ public interface Adjustable
* Removes an adjustment listener from this object.
*
* @param listener the adjustment listener to remove
- * @see AdjustmentEvent
+ * @see java.awt.event.AdjustmentEvent
*/
void removeAdjustmentListener(AdjustmentListener listener);
} // interface Adjustable
diff --git a/libjava/java/awt/BasicStroke.java b/libjava/java/awt/BasicStroke.java
index 2978c6401d7..e302a0ebc9f 100644
--- a/libjava/java/awt/BasicStroke.java
+++ b/libjava/java/awt/BasicStroke.java
@@ -1,5 +1,5 @@
/* BasicStroke.java --
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -69,7 +69,7 @@ public class BasicStroke implements Stroke
* greater than or equal to 1.0f.
* @param dash The array representing the dashing pattern. There must be at
* least one non-zero entry.
- * @param dash_phase is negative and dash is not null.
+ * @param dashPhase is negative and dash is not null.
*
* @exception IllegalArgumentException If one input parameter doesn't meet
* its needs.
diff --git a/libjava/java/awt/Button.java b/libjava/java/awt/Button.java
index 0bb5766dbf0..86cb37cac90 100644
--- a/libjava/java/awt/Button.java
+++ b/libjava/java/awt/Button.java
@@ -1,5 +1,5 @@
/* Button.java -- AWT button widget
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,13 +44,21 @@ import java.awt.peer.ButtonPeer;
import java.lang.reflect.Array;
import java.util.EventListener;
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRelation;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleValue;
+
/**
* This class provides a button widget for the AWT.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey <tromey@cygnus.com>
*/
-public class Button extends Component implements java.io.Serializable
+public class Button extends Component
+ implements java.io.Serializable, Accessible
{
/*
@@ -84,7 +92,102 @@ private transient ActionListener action_listeners;
/*
* The number used to generate the name returned by getName.
*/
- private static transient long next_button_number = 0;
+ private static transient long next_button_number;
+
+ protected class AccessibleAWTButton extends AccessibleAWTComponent
+ implements AccessibleAction, AccessibleValue
+ {
+ protected AccessibleAWTButton() { }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionCount()
+ */
+ public int getAccessibleActionCount()
+ {
+ // Only 1 action possible
+ return 1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int)
+ */
+ public String getAccessibleActionDescription(int i)
+ {
+ // JDK 1.4.2 returns the string "click" for action 0. However, the API
+ // docs don't say what the string to be returned is, beyond being a
+ // description of the action. So we return the same thing for
+ // compatibility with 1.4.2.
+ if (i == 0)
+ return "click";
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#doAccessibleAction(int)
+ */
+ public boolean doAccessibleAction(int i)
+ {
+ if (i != 0)
+ return false;
+ processActionEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand));
+ return true;
+ }
+
+ public String getAccessibleName()
+ {
+ return label;
+ }
+
+ public AccessibleAction getAccessibleAction()
+ {
+ return this;
+ }
+
+ public AccessibleValue getAccessibleValue()
+ {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue()
+ */
+ public Number getCurrentAccessibleValue()
+ {
+ // Docs say return 1 if selected, but buttons can't be selected, right?
+ return new Integer(0);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number)
+ */
+ public boolean setCurrentAccessibleValue(Number number)
+ {
+ // Since there's no selection with buttons, we're ignoring this.
+ // TODO someone who knows shoulw check this.
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue()
+ */
+ public Number getMinimumAccessibleValue()
+ {
+ return new Integer(0);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue()
+ */
+ public Number getMaximumAccessibleValue()
+ {
+ return new Integer(0);
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.PUSH_BUTTON;
+ }
+ }
/*************************************************************************/
@@ -215,6 +318,13 @@ removeActionListener(ActionListener listener)
action_listeners = AWTEventMulticaster.remove(action_listeners, listener);
}
+ /**
+ * Returns all added <code>ActionListener</code> objects.
+ *
+ * @return an array of listeners
+ *
+ * @since 1.4
+ */
public synchronized ActionListener[] getActionListeners()
{
return (ActionListener[])
@@ -222,10 +332,15 @@ removeActionListener(ActionListener listener)
ActionListener.class);
}
-/** Returns all registered EventListers of the given listenerType.
+/**
+ * Returns all registered EventListers of the given listenerType.
* listenerType must be a subclass of EventListener, or a
* ClassClassException is thrown.
*
+ * @param listenerType the listener type to return
+ *
+ * @return an array of listeners
+ *
* @exception ClassCastException If listenerType doesn't specify a class or
* interface that implements @see java.util.EventListener.
*
@@ -314,6 +429,11 @@ paramString()
+ getWidth () + "x" + getHeight () + ",label=" + getLabel ();
}
+public AccessibleContext getAccessibleContext()
+{
+ return new AccessibleAWTButton();
+}
+
/**
* Generate a unique name for this button.
*
diff --git a/libjava/java/awt/Canvas.java b/libjava/java/awt/Canvas.java
index dad86c6e689..d177c9b7d7a 100644
--- a/libjava/java/awt/Canvas.java
+++ b/libjava/java/awt/Canvas.java
@@ -1,4 +1,5 @@
-/* Copyright (C) 1999, 2000, 2002 Free Software Foundation
+/* Canvas.java --
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -37,17 +38,61 @@ exception statement from your version. */
package java.awt;
+import java.awt.image.BufferStrategy;
import java.awt.peer.ComponentPeer;
-
-public class Canvas extends Component implements java.io.Serializable
+import java.io.Serializable;
+
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
+/**
+ * The <code>Canvas</code> component provides a blank rectangular
+ * area, which the client application can use for drawing and for
+ * capturing events. By overriding the <code>paint()</code> method,
+ * the canvas can be used for anything from simple line drawings to
+ * full-scale custom components.
+ *
+ * @author Original author unknown
+ * @author Tom Tromey <tromey@redhat.com>
+ * @author Andrew John Hughes <gnu_andrew@member.fsf.org>
+ * @since 1.0
+ */
+
+public class Canvas
+ extends Component
+ implements Serializable, Accessible
{
+
+ /**
+ * Compatible with Sun's JDK.
+ */
+ private static final long serialVersionUID = -2284879212465893870L;
+
+ /**
+ * The graphics configuration associated with the canvas.
+ */
transient GraphicsConfiguration graphicsConfiguration;
/**
+ * The buffer strategy associated with this canvas.
+ */
+ transient BufferStrategy bufferStrategy;
+
+ /**
* Initializes a new instance of <code>Canvas</code>.
*/
- public Canvas() { }
+ public Canvas()
+ {
+ }
+ /**
+ * Initializes a new instance of <code>Canvas</code>
+ * with the supplied graphics configuration.
+ *
+ * @param graphicsConfiguration the graphics configuration to use
+ * for this particular canvas.
+ */
public Canvas(GraphicsConfiguration graphicsConfiguration)
{
this.graphicsConfiguration = graphicsConfiguration;
@@ -71,9 +116,11 @@ public class Canvas extends Component implements java.io.Serializable
}
/**
- * Repaints the canvas window. This method should be overriden by
+ * Repaints the canvas window. This method should be overridden by
* a subclass to do something useful, as this method simply paints
* the window with the background color.
+ *
+ * @param gfx the <code>Graphics</code> to use for painting
*/
public void paint(Graphics gfx)
{
@@ -86,6 +133,86 @@ public class Canvas extends Component implements java.io.Serializable
gfx.fillRect(0, 0, size.width, size.height);
}
- // Serialization constant
- private static final long serialVersionUID = -2284879212465893870L;
+ /**
+ * This class provides accessibility support for the canvas.
+ */
+ protected class AccessibleAWTCanvas
+ extends AccessibleAWTComponent
+ {
+ /**
+ * For compatability with Sun's JDK
+ */
+ private static final long serialVersionUID = -6325592262103146699L;
+
+ /**
+ * Constructor for the accessible canvas.
+ */
+ protected AccessibleAWTCanvas()
+ {
+ }
+
+ /**
+ * Returns the accessible role for the canvas.
+ *
+ * @return an instance of <code>AccessibleRole</code>, describing
+ * the role of the canvas.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.CANVAS;
+ }
+
+ }
+
+ /**
+ * Gets the AccessibleContext associated with this <code>Canvas</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ {
+ /* Create the context */
+ accessibleContext = new AccessibleAWTCanvas();
+ }
+ return accessibleContext;
+ }
+
+ /**
+ * Returns the buffer strategy used by the canvas.
+ *
+ * @return the buffer strategy.
+ * @since 1.4
+ */
+ public BufferStrategy getBufferStrategy()
+ {
+ return bufferStrategy;
+ }
+
+ /**
+ * Updates the canvas in response to a request to
+ * <code>repaint()</code> it. The canvas is cleared
+ * with the current background colour, before <code>paint()</code>
+ * is called to add the new contents. Subclasses
+ * which override this method should either call this
+ * method via <code>super.update(graphics)</code> or re-implement
+ * this behaviour, so as to ensure that the canvas is
+ * clear before painting takes place.
+ *
+ * @param graphics the graphics context.
+ */
+ public void update(Graphics graphics)
+ {
+ Dimension size;
+
+ /* Clear the canvas */
+ size = getSize();
+ graphics.clearRect(0, 0, size.width, size.height);
+ /* Call the paint method */
+ paint(graphics);
+ }
+
}
diff --git a/libjava/java/awt/CardLayout.java b/libjava/java/awt/CardLayout.java
index fa4f4ec0fe7..e1f3831b30f 100644
--- a/libjava/java/awt/CardLayout.java
+++ b/libjava/java/awt/CardLayout.java
@@ -1,6 +1,5 @@
-// CardLayout.java - Card-based layout engine
-
-/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation
+/* CardLayout.java -- Card-based layout engine
+ Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -39,21 +38,22 @@ exception statement from your version. */
package java.awt;
+import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;
-import java.io.Serializable;
-/** This class implements a card-based layout scheme. Each included
+/**
+ * This class implements a card-based layout scheme. Each included
* component is treated as a card. Only one card can be shown at a
* time. This class includes methods for changing which card is
* shown.
*
- * @author Tom Tromey <tromey@redhat.com>
+ * @author Tom Tromey (tromey@redhat.com)
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class CardLayout implements LayoutManager2, Serializable
{
- static final long serialVersionUID = -4328196481005934313L;
+ private static final long serialVersionUID = -4328196481005934313L;
/**
* Initializes a new instance of <code>CardLayout</code> with horizontal
@@ -67,6 +67,7 @@ public class CardLayout implements LayoutManager2, Serializable
/**
* Create a new <code>CardLayout</code> object with the specified
* horizontal and vertical gaps.
+ *
* @param hgap The horizontal gap
* @param vgap The vertical gap
*/
@@ -77,11 +78,14 @@ public class CardLayout implements LayoutManager2, Serializable
this.tab = new Hashtable ();
}
- /** Add a new component to the layout. The constraint must be a
+ /**
+ * Add a new component to the layout. The constraint must be a
* string which is used to name the component. This string can
* later be used to refer to the particular component.
+ *
* @param comp The component to add
* @param constraints The name by which the component can later be called
+ *
* @exception IllegalArgumentException If `constraints' is not a
* <code>String</code>
*/
@@ -93,10 +97,13 @@ public class CardLayout implements LayoutManager2, Serializable
addLayoutComponent ((String) constraints, comp);
}
- /** Add a new component to the layout. The name can be used later
+ /**
+ * Add a new component to the layout. The name can be used later
* to refer to the component.
+ *
* @param name The name by which the component can later be called
* @param comp The component to add
+ *
* @deprecated This method is deprecated in favor of
* <code>addLayoutComponent(Component, Object)</code>.
*/
@@ -104,13 +111,12 @@ public class CardLayout implements LayoutManager2, Serializable
{
tab.put (name, comp);
// First component added is the default component.
- if (tab.size() == 1)
- comp.setVisible(true);
- else
- comp.setVisible(false);
+ comp.setVisible(tab.size() == 1);
}
- /** Cause the first component in the container to be displayed.
+ /**
+ * Cause the first component in the container to be displayed.
+ *
* @param parent The parent container
*/
public void first (Container parent)
@@ -118,43 +124,63 @@ public class CardLayout implements LayoutManager2, Serializable
gotoComponent (parent, FIRST);
}
- /** Return this layout manager's horizontal gap. */
+ /**
+ * Return this layout manager's horizontal gap.
+ *
+ * @return the horizontal gap
+ */
public int getHgap ()
{
return hgap;
}
- /** Return this layout manager's x alignment. This method always
+ /**
+ * Return this layout manager's x alignment. This method always
* returns Component.CENTER_ALIGNMENT.
+ *
* @param parent Container using this layout manager instance
+ *
+ * @return the x-axis alignment
*/
public float getLayoutAlignmentX (Container parent)
{
return Component.CENTER_ALIGNMENT;
}
- /** Returns this layout manager's y alignment. This method always
+ /**
+ * Returns this layout manager's y alignment. This method always
* returns Component.CENTER_ALIGNMENT.
+ *
* @param parent Container using this layout manager instance
+ *
+ * @return the y-axis alignment
*/
public float getLayoutAlignmentY (Container parent)
{
return Component.CENTER_ALIGNMENT;
}
- /** Return this layout manager's vertical gap. */
+ /**
+ * Return this layout manager's vertical gap.
+ *
+ * @return the vertical gap
+ */
public int getVgap ()
{
return vgap;
}
- /** Invalidate this layout manager's state. */
+ /**
+ * Invalidate this layout manager's state.
+ */
public void invalidateLayout (Container target)
{
// Do nothing.
}
- /** Cause the last component in the container to be displayed.
+ /**
+ * Cause the last component in the container to be displayed.
+ *
* @param parent The parent container
*/
public void last (Container parent)
@@ -190,8 +216,12 @@ public class CardLayout implements LayoutManager2, Serializable
}
}
- /** Get the maximum layout size of the container.
+ /**
+ * Get the maximum layout size of the container.
+ *
* @param target The parent container
+ *
+ * @return the maximum layout size
*/
public Dimension maximumLayoutSize (Container target)
{
@@ -200,17 +230,23 @@ public class CardLayout implements LayoutManager2, Serializable
return getSize (target, MAX);
}
- /** Get the minimum layout size of the container.
+ /**
+ * Get the minimum layout size of the container.
+ *
* @param target The parent container
+ *
+ * @return the minimum layout size
*/
public Dimension minimumLayoutSize (Container target)
{
return getSize (target, MIN);
}
- /** Cause the next component in the container to be displayed. If
+ /**
+ * Cause the next component in the container to be displayed. If
* this current card is the last one in the deck, the first
* component is displayed.
+ *
* @param parent The parent container
*/
public void next (Container parent)
@@ -218,17 +254,23 @@ public class CardLayout implements LayoutManager2, Serializable
gotoComponent (parent, NEXT);
}
- /** Get the preferred layout size of the container.
- * @param target The parent container
+ /**
+ * Get the preferred layout size of the container.
+ *
+ * @param parent The parent container
+ *
+ * @return the preferred layout size
*/
public Dimension preferredLayoutSize (Container parent)
{
return getSize (parent, PREF);
}
- /** Cause the previous component in the container to be displayed.
+ /**
+ * Cause the previous component in the container to be displayed.
* If this current card is the first one in the deck, the last
* component is displayed.
+ *
* @param parent The parent container
*/
public void previous (Container parent)
@@ -236,7 +278,9 @@ public class CardLayout implements LayoutManager2, Serializable
gotoComponent (parent, PREV);
}
- /** Remove the indicated component from this layout manager.
+ /**
+ * Remove the indicated component from this layout manager.
+ *
* @param comp The component to remove
*/
public void removeLayoutComponent (Component comp)
@@ -255,7 +299,9 @@ public class CardLayout implements LayoutManager2, Serializable
}
}
- /** Set this layout manager's horizontal gap.
+ /**
+ * Set this layout manager's horizontal gap.
+ *
* @param hgap The new gap
*/
public void setHgap (int hgap)
@@ -263,7 +309,9 @@ public class CardLayout implements LayoutManager2, Serializable
this.hgap = hgap;
}
- /** Set this layout manager's vertical gap.
+ /**
+ * Set this layout manager's vertical gap.
+ *
* @param vgap The new gap
*/
public void setVgap (int vgap)
@@ -271,8 +319,10 @@ public class CardLayout implements LayoutManager2, Serializable
this.vgap = vgap;
}
- /** Cause the named component to be shown. If the component name is
+ /**
+ * Cause the named component to be shown. If the component name is
* unknown, this method does nothing.
+ *
* @param parent The parent container
* @param name The name of the component to show
*/
@@ -307,7 +357,9 @@ public class CardLayout implements LayoutManager2, Serializable
return getClass ().getName () + "[" + hgap + "," + vgap + "]";
}
- /** This implements first(), last(), next(), and previous().
+ /**
+ * This implements first(), last(), next(), and previous().
+ *
* @param parent The parent container
* @param what The type of goto: FIRST, LAST, NEXT or PREV
*/
@@ -419,13 +471,13 @@ public class CardLayout implements LayoutManager2, Serializable
private Hashtable tab;
// These constants are used by the private gotoComponent method.
- private int FIRST = 0;
- private int LAST = 1;
- private int NEXT = 2;
- private int PREV = 3;
+ private static final int FIRST = 0;
+ private static final int LAST = 1;
+ private static final int NEXT = 2;
+ private static final int PREV = 3;
// These constants are used by the private getSize method.
- private int MIN = 0;
- private int MAX = 1;
- private int PREF = 2;
+ private static final int MIN = 0;
+ private static final int MAX = 1;
+ private static final int PREF = 2;
}
diff --git a/libjava/java/awt/Checkbox.java b/libjava/java/awt/Checkbox.java
index 5e80e1661f6..04ace46cabe 100644
--- a/libjava/java/awt/Checkbox.java
+++ b/libjava/java/awt/Checkbox.java
@@ -43,6 +43,13 @@ import java.awt.event.ItemListener;
import java.awt.peer.CheckboxPeer;
import java.io.Serializable;
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleValue;
+
/**
* This class implements a component which has an on/off state. Two
* or more Checkboxes can be grouped by a CheckboxGroup.
@@ -50,7 +57,8 @@ import java.io.Serializable;
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey <tromey@redhat.com>
*/
-public class Checkbox extends Component implements ItemSelectable, Serializable
+public class Checkbox extends Component
+ implements ItemSelectable, Accessible, Serializable
{
// FIXME: Need readObject/writeObject for this.
@@ -86,6 +94,96 @@ private boolean state;
// The list of listeners for this object.
private transient ItemListener item_listeners;
+protected class AccessibleAWTCheckBox
+ extends AccessibleAWTComponent
+ implements ItemListener, AccessibleAction, AccessibleValue
+{
+
+
+ /* (non-Javadoc)
+ * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
+ */
+ public void itemStateChanged(ItemEvent event)
+ {
+ firePropertyChange(ACCESSIBLE_STATE_PROPERTY,
+ state ? null : AccessibleState.CHECKED,
+ state ? AccessibleState.CHECKED : null);
+ }
+
+ public AccessibleAction getAccessibleAction()
+ {
+ return this;
+ }
+
+ public AccessibleValue getAccessibleValue()
+ {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionCount()
+ */
+ public int getAccessibleActionCount()
+ {
+ // 1.4.1 does this
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int)
+ */
+ public String getAccessibleActionDescription(int i)
+ {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#doAccessibleAction(int)
+ */
+ public boolean doAccessibleAction(int i)
+ {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue()
+ */
+ public Number getCurrentAccessibleValue()
+ {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number)
+ */
+ public boolean setCurrentAccessibleValue(Number number)
+ {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue()
+ */
+ public Number getMinimumAccessibleValue()
+ {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue()
+ */
+ public Number getMaximumAccessibleValue()
+ {
+ return null;
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.CHECK_BOX;
+ }
+
+}
+
/*************************************************************************/
/*
@@ -392,4 +490,11 @@ paramString()
+ "," + super.paramString());
}
+public AccessibleContext getAccessibleContext()
+{
+ AccessibleAWTCheckBox ac = new AccessibleAWTCheckBox();
+ addItemListener(ac);
+ return ac;
+}
+
} // class Checkbox
diff --git a/libjava/java/awt/CheckboxMenuItem.java b/libjava/java/awt/CheckboxMenuItem.java
index c7df075b310..ab4cb60f03c 100644
--- a/libjava/java/awt/CheckboxMenuItem.java
+++ b/libjava/java/awt/CheckboxMenuItem.java
@@ -1,5 +1,5 @@
/* CheckboxMenuItem.java -- A menu option with a checkbox on it.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,7 +41,6 @@ package java.awt;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.peer.CheckboxMenuItemPeer;
-import java.awt.peer.MenuItemPeer;
import java.util.EventListener;
/**
@@ -175,7 +174,7 @@ setState(boolean state)
* Returns an array of length 1 with the menu item label for this object
* if the state is on. Otherwise <code>null</code> is returned.
*
- * @param An array with this menu item's label if it has a state of on,
+ * @return An array with this menu item's label if it has a state of on,
* or <code>null</code> otherwise.
*/
public Object[]
@@ -198,12 +197,9 @@ getSelectedObjects()
public synchronized void
addNotify()
{
- if (peer != null)
- {
- // This choice of toolkit seems unsatisfying, but I'm not sure
- // what else to do.
- peer = getToolkit().createCheckboxMenuItem(this);
- }
+ if (peer == null)
+ peer = getToolkit().createCheckboxMenuItem(this);
+
super.addNotify ();
}
diff --git a/libjava/java/awt/Choice.java b/libjava/java/awt/Choice.java
index b2b597ed06f..89e91ca78b8 100644
--- a/libjava/java/awt/Choice.java
+++ b/libjava/java/awt/Choice.java
@@ -1,5 +1,5 @@
/* Choice.java -- Java choice button widget.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,6 +45,10 @@ import java.io.Serializable;
import java.util.EventListener;
import java.util.Vector;
+import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
/**
* This class implements a drop down choice list.
*
@@ -79,6 +83,53 @@ private int selectedIndex = -1;
// Listener chain
private ItemListener item_listeners;
+ protected class AccessibleAWTChoice
+ extends Component.AccessibleAWTComponent
+ implements AccessibleAction
+ {
+ public AccessibleAction getAccessibleAction()
+ {
+ return this;
+ }
+
+ // FIXME: I think this is right, but should be checked by someone who
+ // knows better.
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.POPUP_MENU;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionCount()
+ */
+ public int getAccessibleActionCount()
+ {
+ return pItems.size();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int)
+ */
+ public String getAccessibleActionDescription(int i)
+ {
+ return (String) pItems.get(i);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#doAccessibleAction(int)
+ */
+ public boolean doAccessibleAction(int i)
+ {
+ if (i < 0 || i >= pItems.size())
+ return false;
+
+ Choice.this.processItemEvent(new ItemEvent(Choice.this,
+ ItemEvent.ITEM_STATE_CHANGED,
+ this, ItemEvent.SELECTED));
+ return true;
+ }
+ }
+
/*************************************************************************/
/*
@@ -169,6 +220,8 @@ add(String item)
ChoicePeer cp = (ChoicePeer) peer;
cp.add (item, i);
}
+ else if (selectedIndex == -1)
+ select(0);
}
/*************************************************************************/
@@ -218,6 +271,8 @@ insert(String item, int index)
ChoicePeer cp = (ChoicePeer) peer;
cp.add (item, index);
}
+ else if (selectedIndex == -1 || selectedIndex >= index)
+ select(0);
}
/*************************************************************************/
@@ -261,6 +316,13 @@ remove(int index)
ChoicePeer cp = (ChoicePeer) peer;
cp.remove (index);
}
+ else
+ {
+ if (getItemCount() == 0)
+ selectedIndex = -1;
+ else if (index == selectedIndex)
+ select(0);
+ }
if (selectedIndex > index)
--selectedIndex;
@@ -501,4 +563,9 @@ paramString()
{
return (ItemListener[]) getListeners (ItemListener.class);
}
+
+ public AccessibleContext getAccessibleContext()
+ {
+ return new AccessibleAWTChoice();
+ }
} // class Choice
diff --git a/libjava/java/awt/Component.java b/libjava/java/awt/Component.java
index 90aaaf91f52..cb47f777acb 100644
--- a/libjava/java/awt/Component.java
+++ b/libjava/java/awt/Component.java
@@ -1,5 +1,5 @@
/* Component.java -- a graphics component
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -47,16 +47,16 @@ import java.awt.event.FocusListener;
import java.awt.event.HierarchyBoundsListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
import java.awt.event.InputEvent;
import java.awt.event.InputMethodEvent;
import java.awt.event.InputMethodListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
-import java.awt.event.MouseWheelListener;
import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
import java.awt.event.PaintEvent;
import java.awt.event.WindowEvent;
import java.awt.im.InputContext;
@@ -70,8 +70,8 @@ import java.awt.peer.ComponentPeer;
import java.awt.peer.LightweightPeer;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
-import java.io.ObjectInputStream;
import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
@@ -84,6 +84,7 @@ import java.util.Iterator;
import java.util.Locale;
import java.util.Set;
import java.util.Vector;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleComponent;
import javax.accessibility.AccessibleContext;
@@ -293,7 +294,7 @@ public abstract class Component
* @see #getLocale()
* @see #setLocale(Locale)
*/
- Locale locale;
+ Locale locale = Locale.getDefault ();
/**
* True if the object should ignore repaint events (usually because it is
@@ -575,8 +576,6 @@ public abstract class Component
{
incrementalDraw = Boolean.getBoolean ("awt.image.incrementalDraw");
redrawRate = Long.getLong ("awt.image.redrawrate");
- // Set the default KeyboardFocusManager.
- KeyboardFocusManager.setCurrentKeyboardFocusManager (null);
}
// Public and protected API.
@@ -785,13 +784,15 @@ public abstract class Component
* events).
*
* @param enabled true to enable this component
+ *
* @see #isEnabled()
* @see #isLightweight()
+ *
* @since 1.1
*/
- public void setEnabled(boolean b)
+ public void setEnabled(boolean enabled)
{
- enable (b);
+ enable(enabled);
}
/**
@@ -810,14 +811,15 @@ public abstract class Component
* Enables or disables this component.
*
* @param enabled true to enable this component
+ *
* @deprecated use {@link #setEnabled(boolean)} instead
*/
- public void enable(boolean b)
+ public void enable(boolean enabled)
{
- if (b)
- enable ();
+ if (enabled)
+ enable();
else
- disable ();
+ disable();
}
/**
@@ -865,15 +867,17 @@ public abstract class Component
* not show the component, if a parent is invisible.
*
* @param visible true to make this component visible
+ *
* @see #isVisible()
+ *
* @since 1.1
*/
- public void setVisible(boolean b)
+ public void setVisible(boolean visible)
{
// Inspection by subclassing shows that Sun's implementation calls
// show(boolean) which then calls show() or hide(). It is the show()
// method that is overriden in subclasses like Window.
- show (b);
+ show(visible);
}
/**
@@ -904,14 +908,15 @@ public abstract class Component
* Makes this component visible or invisible.
*
* @param visible true to make this component visible
+ *
* @deprecated use {@link #setVisible(boolean)} instead
*/
- public void show(boolean b)
+ public void show(boolean visible)
{
- if (b)
- show ();
+ if (visible)
+ show();
else
- hide ();
+ hide();
}
/**
@@ -1041,16 +1046,21 @@ public abstract class Component
* Sets the font for this component to the specified font. This is a bound
* property.
*
- * @param font the new font for this component
+ * @param newFont the new font for this component
+ *
* @see #getFont()
*/
- public void setFont(Font f)
+ public void setFont(Font newFont)
{
- firePropertyChange("font", font, f);
+ if (font == newFont)
+ return;
+
+ Font oldFont = font;
+ font = newFont;
if (peer != null)
- peer.setFont(f);
+ peer.setFont(font);
+ firePropertyChange("font", oldFont, newFont);
invalidate();
- font = f;
}
/**
@@ -1087,12 +1097,16 @@ public abstract class Component
* Sets the locale for this component to the specified locale. This is a
* bound property.
*
- * @param locale the new locale for this component
+ * @param newLocale the new locale for this component
*/
- public void setLocale(Locale l)
+ public void setLocale(Locale newLocale)
{
- firePropertyChange("locale", locale, l);
- locale = l;
+ if (locale == newLocale)
+ return;
+
+ Locale oldLocale = locale;
+ locale = newLocale;
+ firePropertyChange("locale", oldLocale, newLocale);
// New writing/layout direction or more/less room for localized labels.
invalidate();
}
@@ -1366,7 +1380,7 @@ public abstract class Component
shouldRepaintSelf = parentBounds.intersects(newBounds);
}
- if (shouldRepaintParent)
+ if (shouldRepaintParent && parent != null)
parent.repaint(oldx, oldy, oldwidth, oldheight);
if (shouldRepaintSelf)
repaint();
@@ -1787,7 +1801,8 @@ public abstract class Component
* relative to this component. Subclasses should call either
* <code>super.update(g)</code> or <code>paint(g)</code>.
*
- * @param graphics the graphics context for this update
+ * @param g the graphics context for this update
+ *
* @see #paint(Graphics)
* @see #repaint()
*/
@@ -1808,7 +1823,8 @@ public abstract class Component
/**
* Paints this entire component, including any sub-components.
*
- * @param graphics the graphics context for this paint job
+ * @param g the graphics context for this paint job
+ *
* @see #paint(Graphics)
*/
public void paintAll(Graphics g)
@@ -1870,8 +1886,8 @@ public abstract class Component
* @param tm milliseconds before this component should be repainted
* @param x the X coordinate of the upper left of the region to repaint
* @param y the Y coordinate of the upper left of the region to repaint
- * @param w the width of the region to repaint
- * @param h the height of the region to repaint
+ * @param width the width of the region to repaint
+ * @param height the height of the region to repaint
* @see #update(Graphics)
*/
public void repaint(long tm, int x, int y, int width, int height)
@@ -1891,7 +1907,8 @@ public abstract class Component
* done in a different manner from painting. However, the implementation
* in this class simply calls the <code>paint()</code> method.
*
- * @param graphics the graphics context of the print device
+ * @param g the graphics context of the print device
+ *
* @see #paint(Graphics)
*/
public void print(Graphics g)
@@ -1905,7 +1922,8 @@ public abstract class Component
* painting. However, the implementation in this class simply calls the
* <code>paintAll()</code> method.
*
- * @param graphics the graphics context of the print device
+ * @param g the graphics context of the print device
+ *
* @see #paintAll(Graphics)
*/
public void printAll(Graphics g)
@@ -1923,7 +1941,7 @@ public abstract class Component
*
* <p>The coordinate system used depends on the particular flags.
*
- * @param image the image that has been updated
+ * @param img the image that has been updated
* @param flags tlags as specified in <code>ImageObserver</code>
* @param x the X coordinate
* @param y the Y coordinate
@@ -2270,7 +2288,7 @@ public abstract class Component
{
boolean handled = handleEvent (e);
- if (!handled)
+ if (!handled && getParent() != null)
// FIXME: need to translate event coordinates to parent's
// coordinate space.
handled = getParent ().postEvent (e);
@@ -2289,9 +2307,9 @@ public abstract class Component
* @see #getComponentListeners()
* @since 1.1
*/
- public synchronized void addComponentListener(ComponentListener l)
+ public synchronized void addComponentListener(ComponentListener listener)
{
- componentListener = AWTEventMulticaster.add(componentListener, l);
+ componentListener = AWTEventMulticaster.add(componentListener, listener);
if (componentListener != null)
enableEvents(AWTEvent.COMPONENT_EVENT_MASK);
}
@@ -2306,9 +2324,9 @@ public abstract class Component
* @see #getComponentListeners()
* @since 1.1
*/
- public synchronized void removeComponentListener(ComponentListener l)
+ public synchronized void removeComponentListener(ComponentListener listener)
{
- componentListener = AWTEventMulticaster.remove(componentListener, l);
+ componentListener = AWTEventMulticaster.remove(componentListener, listener);
}
/**
@@ -2337,9 +2355,9 @@ public abstract class Component
* @see #getFocusListeners()
* @since 1.1
*/
- public synchronized void addFocusListener(FocusListener l)
+ public synchronized void addFocusListener(FocusListener listener)
{
- focusListener = AWTEventMulticaster.add(focusListener, l);
+ focusListener = AWTEventMulticaster.add(focusListener, listener);
if (focusListener != null)
enableEvents(AWTEvent.FOCUS_EVENT_MASK);
}
@@ -2354,9 +2372,9 @@ public abstract class Component
* @see #getFocusListeners()
* @since 1.1
*/
- public synchronized void removeFocusListener(FocusListener l)
+ public synchronized void removeFocusListener(FocusListener listener)
{
- focusListener = AWTEventMulticaster.remove(focusListener, l);
+ focusListener = AWTEventMulticaster.remove(focusListener, listener);
}
/**
@@ -2384,9 +2402,9 @@ public abstract class Component
* @see #getHierarchyListeners()
* @since 1.3
*/
- public synchronized void addHierarchyListener(HierarchyListener l)
+ public synchronized void addHierarchyListener(HierarchyListener listener)
{
- hierarchyListener = AWTEventMulticaster.add(hierarchyListener, l);
+ hierarchyListener = AWTEventMulticaster.add(hierarchyListener, listener);
if (hierarchyListener != null)
enableEvents(AWTEvent.HIERARCHY_EVENT_MASK);
}
@@ -2401,9 +2419,9 @@ public abstract class Component
* @see #getHierarchyListeners()
* @since 1.3
*/
- public synchronized void removeHierarchyListener(HierarchyListener l)
+ public synchronized void removeHierarchyListener(HierarchyListener listener)
{
- hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, l);
+ hierarchyListener = AWTEventMulticaster.remove(hierarchyListener, listener);
}
/**
@@ -2433,10 +2451,10 @@ public abstract class Component
* @since 1.3
*/
public synchronized void
- addHierarchyBoundsListener(HierarchyBoundsListener l)
+ addHierarchyBoundsListener(HierarchyBoundsListener listener)
{
hierarchyBoundsListener =
- AWTEventMulticaster.add(hierarchyBoundsListener, l);
+ AWTEventMulticaster.add(hierarchyBoundsListener, listener);
if (hierarchyBoundsListener != null)
enableEvents(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK);
}
@@ -2452,10 +2470,10 @@ public abstract class Component
* @since 1.3
*/
public synchronized void
- removeHierarchyBoundsListener(HierarchyBoundsListener l)
+ removeHierarchyBoundsListener(HierarchyBoundsListener listener)
{
hierarchyBoundsListener =
- AWTEventMulticaster.remove(hierarchyBoundsListener, l);
+ AWTEventMulticaster.remove(hierarchyBoundsListener, listener);
}
/**
@@ -2484,9 +2502,9 @@ public abstract class Component
* @see #getKeyListeners()
* @since 1.1
*/
- public synchronized void addKeyListener(KeyListener l)
+ public synchronized void addKeyListener(KeyListener listener)
{
- keyListener = AWTEventMulticaster.add(keyListener, l);
+ keyListener = AWTEventMulticaster.add(keyListener, listener);
if (keyListener != null)
enableEvents(AWTEvent.KEY_EVENT_MASK);
}
@@ -2501,9 +2519,9 @@ public abstract class Component
* @see #getKeyListeners()
* @since 1.1
*/
- public synchronized void removeKeyListener(KeyListener l)
+ public synchronized void removeKeyListener(KeyListener listener)
{
- keyListener = AWTEventMulticaster.remove(keyListener, l);
+ keyListener = AWTEventMulticaster.remove(keyListener, listener);
}
/**
@@ -2531,9 +2549,9 @@ public abstract class Component
* @see #getMouseListeners()
* @since 1.1
*/
- public synchronized void addMouseListener(MouseListener l)
+ public synchronized void addMouseListener(MouseListener listener)
{
- mouseListener = AWTEventMulticaster.add(mouseListener, l);
+ mouseListener = AWTEventMulticaster.add(mouseListener, listener);
if (mouseListener != null)
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
}
@@ -2548,9 +2566,9 @@ public abstract class Component
* @see #getMouseListeners()
* @since 1.1
*/
- public synchronized void removeMouseListener(MouseListener l)
+ public synchronized void removeMouseListener(MouseListener listener)
{
- mouseListener = AWTEventMulticaster.remove(mouseListener, l);
+ mouseListener = AWTEventMulticaster.remove(mouseListener, listener);
}
/**
@@ -2578,9 +2596,9 @@ public abstract class Component
* @see #getMouseMotionListeners()
* @since 1.1
*/
- public synchronized void addMouseMotionListener(MouseMotionListener l)
+ public synchronized void addMouseMotionListener(MouseMotionListener listener)
{
- mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, l);
+ mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, listener);
if (mouseMotionListener != null)
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
}
@@ -2595,9 +2613,9 @@ public abstract class Component
* @see #getMouseMotionListeners()
* @since 1.1
*/
- public synchronized void removeMouseMotionListener(MouseMotionListener l)
+ public synchronized void removeMouseMotionListener(MouseMotionListener listener)
{
- mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, l);
+ mouseMotionListener = AWTEventMulticaster.remove(mouseMotionListener, listener);
}
/**
@@ -2627,9 +2645,9 @@ public abstract class Component
* @see #getMouseWheelListeners()
* @since 1.4
*/
- public synchronized void addMouseWheelListener(MouseWheelListener l)
+ public synchronized void addMouseWheelListener(MouseWheelListener listener)
{
- mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener, l);
+ mouseWheelListener = AWTEventMulticaster.add(mouseWheelListener, listener);
if (mouseWheelListener != null)
enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
}
@@ -2645,9 +2663,9 @@ public abstract class Component
* @see #getMouseWheelListeners()
* @since 1.4
*/
- public synchronized void removeMouseWheelListener(MouseWheelListener l)
+ public synchronized void removeMouseWheelListener(MouseWheelListener listener)
{
- mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, l);
+ mouseWheelListener = AWTEventMulticaster.remove(mouseWheelListener, listener);
}
/**
@@ -2677,9 +2695,9 @@ public abstract class Component
* @see #getInputMethodRequests()
* @since 1.2
*/
- public synchronized void addInputMethodListener(InputMethodListener l)
+ public synchronized void addInputMethodListener(InputMethodListener listener)
{
- inputMethodListener = AWTEventMulticaster.add(inputMethodListener, l);
+ inputMethodListener = AWTEventMulticaster.add(inputMethodListener, listener);
if (inputMethodListener != null)
enableEvents(AWTEvent.INPUT_METHOD_EVENT_MASK);
}
@@ -2694,9 +2712,9 @@ public abstract class Component
* @see #getInputMethodRequests()
* @since 1.2
*/
- public synchronized void removeInputMethodListener(InputMethodListener l)
+ public synchronized void removeInputMethodListener(InputMethodListener listener)
{
- inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, l);
+ inputMethodListener = AWTEventMulticaster.remove(inputMethodListener, listener);
}
/**
@@ -2858,7 +2876,7 @@ public abstract class Component
* Processes the specified event. In this class, this method simply
* calls one of the more specific event handlers.
*
- * @param event the event to process
+ * @param e the event to process
* @throws NullPointerException if e is null
* @see #processComponentEvent(ComponentEvent)
* @see #processFocusEvent(FocusEvent)
@@ -2909,7 +2927,7 @@ public abstract class Component
* enabled. This method passes the event along to any listeners
* that are attached.
*
- * @param event the <code>ComponentEvent</code> to process
+ * @param e the <code>ComponentEvent</code> to process
* @throws NullPointerException if e is null
* @see ComponentListener
* @see #addComponentListener(ComponentListener)
@@ -2942,7 +2960,7 @@ public abstract class Component
* enabled. This method passes the event along to any listeners
* that are attached.
*
- * @param event the <code>FocusEvent</code> to process
+ * @param e the <code>FocusEvent</code> to process
* @throws NullPointerException if e is null
* @see FocusListener
* @see #addFocusListener(FocusListener)
@@ -2970,7 +2988,7 @@ public abstract class Component
* enabled. This method passes the event along to any listeners
* that are attached.
*
- * @param event the <code>KeyEvent</code> to process
+ * @param e the <code>KeyEvent</code> to process
* @throws NullPointerException if e is null
* @see KeyListener
* @see #addKeyListener(KeyListener)
@@ -3000,7 +3018,7 @@ public abstract class Component
* enabled. This method passes the event along to any listeners
* that are attached.
*
- * @param event the <code>MouseEvent</code> to process
+ * @param e the <code>MouseEvent</code> to process
* @throws NullPointerException if e is null
* @see MouseListener
* @see #addMouseListener(MouseListener)
@@ -3037,7 +3055,7 @@ public abstract class Component
* enabled. This method passes the event along to any listeners
* that are attached.
*
- * @param event the <code>MouseMotionEvent</code> to process
+ * @param e the <code>MouseMotionEvent</code> to process
* @throws NullPointerException if e is null
* @see MouseMotionListener
* @see #addMouseMotionListener(MouseMotionListener)
@@ -3065,7 +3083,7 @@ public abstract class Component
* enabled. This method passes the event along to any listeners that are
* attached.
*
- * @param event the <code>MouseWheelEvent</code> to process
+ * @param e the <code>MouseWheelEvent</code> to process
* @throws NullPointerException if e is null
* @see MouseWheelListener
* @see #addMouseWheelListener(MouseWheelListener)
@@ -3087,7 +3105,7 @@ public abstract class Component
* enabled. This method passes the event along to any listeners that are
* attached.
*
- * @param event the <code>InputMethodEvent</code> to process
+ * @param e the <code>InputMethodEvent</code> to process
* @throws NullPointerException if e is null
* @see InputMethodListener
* @see #addInputMethodListener(InputMethodListener)
@@ -3114,7 +3132,7 @@ public abstract class Component
* are enabled. This method passes the event along to any listeners that are
* attached.
*
- * @param event the <code>HierarchyEvent</code> to process
+ * @param e the <code>HierarchyEvent</code> to process
* @throws NullPointerException if e is null
* @see HierarchyListener
* @see #addHierarchyListener(HierarchyListener)
@@ -3134,7 +3152,7 @@ public abstract class Component
* are enabled. This method passes the event along to any listeners that are
* attached.
*
- * @param event the <code>HierarchyEvent</code> to process
+ * @param e the <code>HierarchyEvent</code> to process
* @throws NullPointerException if e is null
* @see HierarchyBoundsListener
* @see #addHierarchyBoundsListener(HierarchyBoundsListener)
@@ -3587,11 +3605,16 @@ public abstract class Component
*
* @param id one of FORWARD_TRAVERSAL_KEYS, BACKWARD_TRAVERSAL_KEYS,
* or UP_CYCLE_TRAVERSAL_KEYS
+ *
+ * @return set of traversal keys
+ *
* @throws IllegalArgumentException if id is invalid
+ *
* @see #setFocusTraversalKeys (int, Set)
* @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
* @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
* @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
+ *
* @since 1.4
*/
public Set getFocusTraversalKeys (int id)
@@ -4087,8 +4110,10 @@ public abstract class Component
/**
* Adds the specified popup menu to this component.
*
- * @param menu the popup menu to be added
+ * @param popup the popup menu to be added
+ *
* @see #remove(MenuComponent)
+ *
* @since 1.1
*/
public synchronized void add(PopupMenu popup)
@@ -4107,7 +4132,7 @@ public abstract class Component
/**
* Removes the specified popup menu from this component.
*
- * @param menu the popup menu to remove
+ * @param popup the popup menu to remove
* @see #add(PopupMenu)
* @since 1.1
*/
@@ -4168,7 +4193,7 @@ public abstract class Component
/**
* Prints a listing of this component to the specified print stream.
*
- * @param stream the <code>PrintStream</code> to print to
+ * @param out the <code>PrintStream</code> to print to
*/
public void list(PrintStream out)
{
@@ -4179,7 +4204,7 @@ public abstract class Component
* Prints a listing of this component to the specified print stream,
* starting at the specified indentation point.
*
- * @param stream the <code>PrintStream</code> to print to
+ * @param out the <code>PrintStream</code> to print to
* @param indent the indentation point
*/
public void list(PrintStream out, int indent)
@@ -4192,7 +4217,7 @@ public abstract class Component
/**
* Prints a listing of this component to the specified print writer.
*
- * @param writer the <code>PrintWrinter</code> to print to
+ * @param out the <code>PrintWrinter</code> to print to
* @since 1.1
*/
public void list(PrintWriter out)
@@ -4204,7 +4229,7 @@ public abstract class Component
* Prints a listing of this component to the specified print writer,
* starting at the specified indentation point.
*
- * @param writer the <code>PrintWriter</code> to print to
+ * @param out the <code>PrintWriter</code> to print to
* @param indent the indentation point
* @since 1.1
*/
@@ -4505,7 +4530,7 @@ p * <li>the set of backward traversal keys
*
* @return an AWT 1.0 event representing e
*/
- private Event translateEvent (AWTEvent e)
+ static Event translateEvent (AWTEvent e)
{
Component target = (Component) e.getSource ();
Event translated = null;
diff --git a/libjava/java/awt/Container.java b/libjava/java/awt/Container.java
index e0ad22c4750..6c835d23d8e 100644
--- a/libjava/java/awt/Container.java
+++ b/libjava/java/awt/Container.java
@@ -35,28 +35,29 @@ 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.awt;
-import java.awt.event.AWTEventListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
-import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
import java.awt.peer.ContainerPeer;
import java.awt.peer.LightweightPeer;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
-import java.io.ObjectInputStream;
import java.io.IOException;
+import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.util.Collections;
import java.util.EventListener;
-import java.util.Iterator;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Set;
+
import javax.accessibility.Accessible;
import javax.swing.SwingUtilities;
@@ -146,7 +147,7 @@ public class Container extends Component
/**
* Returns the component at the specified index.
*
- * @param index The index of the component to retrieve.
+ * @param n The index of the component to retrieve.
*
* @return The requested component.
*
@@ -230,7 +231,7 @@ public class Container extends Component
* Adds the specified component to this container at the end of the
* component list.
*
- * @param component The component to add to the container.
+ * @param comp The component to add to the container.
*
* @return The same component that was added.
*/
@@ -246,7 +247,7 @@ public class Container extends Component
* <code>add(Component, Object)</code>.
*
* @param name The name of the component to be added.
- * @param component The component to be added.
+ * @param comp The component to be added.
*
* @return The same component that was added.
*
@@ -262,7 +263,7 @@ public class Container extends Component
* Adds the specified component to this container at the specified index
* in the component list.
*
- * @param component The component to be added.
+ * @param comp The component to be added.
* @param index The index in the component list to insert this child
* at, or -1 to add at the end of the list.
*
@@ -281,7 +282,7 @@ public class Container extends Component
* component list. The layout manager will use the specified constraints
* when laying out this component.
*
- * @param component The component to be added to this container.
+ * @param comp The component to be added to this container.
* @param constraints The layout constraints for this component.
*/
public void add(Component comp, Object constraints)
@@ -294,7 +295,7 @@ public class Container extends Component
* in the component list. The layout manager will use the specified
* constraints when layout out this component.
*
- * @param component The component to be added.
+ * @param comp The component to be added.
* @param constraints The layout constraints for this component.
* @param index The index in the component list to insert this child
* at, or -1 to add at the end of the list.
@@ -313,7 +314,7 @@ public class Container extends Component
* method. Any subclass doing this must call the superclass version of
* this method in order to ensure proper functioning of the container.
*
- * @param component The component to be added.
+ * @param comp The component to be added.
* @param constraints The layout constraints for this component, or
* <code>null</code> if there are no constraints.
* @param index The index in the component list to insert this child
@@ -339,8 +340,6 @@ public class Container extends Component
comp.parent = this;
if (peer != null)
{
- comp.addNotify();
-
if (comp.isLightweight ())
{
enableEvents (comp.eventMask);
@@ -527,7 +526,7 @@ public class Container extends Component
/**
* Recursively invalidates the container tree.
*/
- private void invalidateTree()
+ void invalidateTree()
{
for (int i = 0; i < ncomponents; i++)
{
@@ -554,10 +553,19 @@ public class Container extends Component
cPeer.beginValidate();
}
- doLayout();
for (int i = 0; i < ncomponents; ++i)
{
Component comp = component[i];
+
+ if (comp.getPeer () == null)
+ comp.addNotify();
+ }
+
+ doLayout ();
+ for (int i = 0; i < ncomponents; ++i)
+ {
+ Component comp = component[i];
+
if (! comp.isValid())
{
if (comp instanceof Container)
@@ -572,8 +580,8 @@ public class Container extends Component
}
/* children will call invalidate() when they are layed out. It
- is therefore imporant that valid is not set to true
- before after the children has been layed out. */
+ is therefore important that valid is not set to true
+ until after the children have been layed out. */
valid = true;
if (cPeer != null)
@@ -698,12 +706,14 @@ public class Container extends Component
* a superclass method so that lightweight components are properly
* drawn.
*
- * @param graphics The graphics context for this paint job.
+ * @param g The graphics context for this paint job.
*/
public void paint(Graphics g)
{
if (!isShowing())
return;
+ // Paint self first.
+ super.paint(g);
// Visit heavyweights as well, in case they were
// erased when we cleared the background for this container.
visitChildren(g, GfxPaintVisitor.INSTANCE, false);
@@ -716,7 +726,7 @@ public class Container extends Component
* a superclass method so that lightweight components are properly
* drawn.
*
- * @param graphics The graphics context for this update.
+ * @param g The graphics context for this update.
*/
public void update(Graphics g)
{
@@ -730,7 +740,7 @@ public class Container extends Component
* a superclass method so that lightweight components are properly
* drawn.
*
- * @param graphics The graphics context for this print job.
+ * @param g The graphics context for this print job.
*/
public void print(Graphics g)
{
@@ -741,7 +751,7 @@ public class Container extends Component
/**
* Paints all of the components in this container.
*
- * @param graphics The graphics context for this paint job.
+ * @param g The graphics context for this paint job.
*/
public void paintComponents(Graphics g)
{
@@ -752,7 +762,7 @@ public class Container extends Component
/**
* Prints all of the components in this container.
*
- * @param graphics The graphics context for this print job.
+ * @param g The graphics context for this print job.
*/
public void printComponents(Graphics g)
{
@@ -766,9 +776,9 @@ public class Container extends Component
*
* @param listener The listener to add.
*/
- public synchronized void addContainerListener(ContainerListener l)
+ public synchronized void addContainerListener(ContainerListener listener)
{
- containerListener = AWTEventMulticaster.add(containerListener, l);
+ containerListener = AWTEventMulticaster.add(containerListener, listener);
}
/**
@@ -777,9 +787,9 @@ public class Container extends Component
*
* @param listener The listener to remove.
*/
- public synchronized void removeContainerListener(ContainerListener l)
+ public synchronized void removeContainerListener(ContainerListener listener)
{
- containerListener = AWTEventMulticaster.remove(containerListener, l);
+ containerListener = AWTEventMulticaster.remove(containerListener, listener);
}
/**
@@ -815,7 +825,7 @@ public class Container extends Component
* <code>ContainerEvent</code>, otherwise it calls the superclass
* method.
*
- * @param event The event to be processed.
+ * @param e The event to be processed.
*/
protected void processEvent(AWTEvent e)
{
@@ -829,7 +839,7 @@ public class Container extends Component
* Called when a container event occurs if container events are enabled.
* This method calls any registered listeners.
*
- * @param event The event that occurred.
+ * @param e The event that occurred.
*/
protected void processContainerEvent(ContainerEvent e)
{
@@ -850,7 +860,7 @@ public class Container extends Component
/**
* AWT 1.0 event processor.
*
- * @param event The event that occurred.
+ * @param e The event that occurred.
*
* @deprecated use {@link #dispatchEvent(AWTEvent)} instead
*/
@@ -895,7 +905,8 @@ public class Container extends Component
* unless the point does not exist within this container, in which
* case <code>null</code> is returned.
*
- * @param point The point to return the component at.
+ * @param x The x position of the point to return the component at.
+ * @param y The y position of the point to return the component at.
*
* @return The component containing the specified point, or <code>null</code>
* if there is no such point.
@@ -931,7 +942,7 @@ public class Container extends Component
* unless the point does not exist within this container, in which
* case <code>null</code> is returned.
*
- * @param point The point to return the component at.
+ * @param p The point to return the component at.
* @return The component containing the specified point, or <code>null</code>
* if there is no such point.
*/
@@ -1007,7 +1018,7 @@ public class Container extends Component
* Tests whether or not the specified component is contained within
* this components subtree.
*
- * @param component The component to test.
+ * @param comp The component to test.
*
* @return <code>true</code> if this container is an ancestor of the
* specified component, <code>false</code> otherwise.
@@ -1046,7 +1057,7 @@ public class Container extends Component
* Writes a listing of this container to the specified stream starting
* at the specified indentation point.
*
- * @param stream The <code>PrintStream</code> to write to.
+ * @param out The <code>PrintStream</code> to write to.
* @param indent The indentation point.
*/
public void list(PrintStream out, int indent)
@@ -1063,7 +1074,7 @@ public class Container extends Component
* Writes a listing of this container to the specified stream starting
* at the specified indentation point.
*
- * @param stream The <code>PrintWriter</code> to write to.
+ * @param out The <code>PrintWriter</code> to write to.
* @param indent The indentation point.
*/
public void list(PrintWriter out, int indent)
diff --git a/libjava/java/awt/DefaultKeyboardFocusManager.java b/libjava/java/awt/DefaultKeyboardFocusManager.java
index 7912e29f056..800b01d4639 100644
--- a/libjava/java/awt/DefaultKeyboardFocusManager.java
+++ b/libjava/java/awt/DefaultKeyboardFocusManager.java
@@ -1,5 +1,5 @@
/* DefaultKeyboardFocusManager.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,15 @@ exception statement from your version. */
package java.awt;
-import java.util.*;
-import java.awt.event.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowEvent;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
// FIXME: finish documentation
public class DefaultKeyboardFocusManager extends KeyboardFocusManager
@@ -164,18 +171,15 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager
if (e.id == FocusEvent.FOCUS_GAINED)
{
- if (((FocusEvent) e).isTemporary ())
- setGlobalFocusOwner (target);
- else
- setGlobalPermanentFocusOwner (target);
- }
- else if (e.id == FocusEvent.FOCUS_LOST)
- {
- // We need to set the window's focus owner here; we can't
- // set it when the window loses focus because by that time
- // the previous focus owner has already lost focus
- // (FOCUS_LOST events are delivered before
- // WINDOW_LOST_FOCUS events).
+ if (! (target instanceof Window))
+ {
+ if (((FocusEvent) e).isTemporary ())
+ setGlobalFocusOwner (target);
+ else
+ setGlobalPermanentFocusOwner (target);
+ }
+
+ // Keep track of this window's focus owner.
// Find the target Component's top-level ancestor.
Container parent = target.getParent ();
@@ -188,9 +192,12 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager
(Window) target : (Window) parent;
Component focusOwner = getFocusOwner ();
- if (focusOwner != null)
+ if (focusOwner != null
+ && ! (focusOwner instanceof Window))
toplevel.setFocusOwner (focusOwner);
-
+ }
+ else if (e.id == FocusEvent.FOCUS_LOST)
+ {
if (((FocusEvent) e).isTemporary ())
setGlobalFocusOwner (null);
else
diff --git a/libjava/java/awt/EventDispatchThread.java b/libjava/java/awt/EventDispatchThread.java
index 89b6095578f..0803ff675c8 100644
--- a/libjava/java/awt/EventDispatchThread.java
+++ b/libjava/java/awt/EventDispatchThread.java
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000, 2002 Free Software Foundation
+/* EventDispatchThread.java -
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -34,22 +35,22 @@ 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. */
-/** @author Bryce McKinlay */
-
-/* Status: believed complete, but untested. */
-
package java.awt;
+/**
+ * @author Bryce McKinlay
+ * @status believed complete, but untested.
+ */
class EventDispatchThread extends Thread
{
- private static int dispatchThreadNum = 1;
+ private static int dispatchThreadNum;
private EventQueue queue;
EventDispatchThread(EventQueue queue)
{
super();
- setName("AWT-EventQueue-" + dispatchThreadNum++);
+ setName("AWT-EventQueue-" + ++dispatchThreadNum);
this.queue = queue;
setPriority(NORM_PRIORITY + 1);
start();
diff --git a/libjava/java/awt/EventQueue.java b/libjava/java/awt/EventQueue.java
index 1c794d43870..fd1c8062d71 100644
--- a/libjava/java/awt/EventQueue.java
+++ b/libjava/java/awt/EventQueue.java
@@ -155,7 +155,7 @@ public class EventQueue
/**
* Posts a new event to the queue.
*
- * @param event The event to post to the queue.
+ * @param evt The event to post to the queue.
*
* @exception NullPointerException If event is null.
*/
diff --git a/libjava/java/awt/FileDialog.java b/libjava/java/awt/FileDialog.java
index 854d092f016..e345018550a 100644
--- a/libjava/java/awt/FileDialog.java
+++ b/libjava/java/awt/FileDialog.java
@@ -1,5 +1,5 @@
/* FileDialog.java -- A filename selection dialog box
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,7 +39,6 @@ exception statement from your version. */
package java.awt;
import java.awt.peer.FileDialogPeer;
-import java.awt.peer.DialogPeer;
import java.io.FilenameFilter;
import java.io.Serializable;
@@ -262,7 +261,7 @@ setFile(String file)
/**
* Returns the filename filter being used by this dialog.
*
- * @param The filename filter being used by this dialog.
+ * @return The filename filter being used by this dialog.
*/
public FilenameFilter
getFilenameFilter()
diff --git a/libjava/java/awt/FlowLayout.java b/libjava/java/awt/FlowLayout.java
index 98d74941ea8..eb2bc98cb1b 100644
--- a/libjava/java/awt/FlowLayout.java
+++ b/libjava/java/awt/FlowLayout.java
@@ -1,6 +1,5 @@
-// FlowLayout.java - Grid-based layout engine
-
-/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation
+/* FlowLayout.java -- Grid-based layout engine
+ Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -47,7 +46,7 @@ import java.io.Serializable;
* supports horizontal and vertical gaps. These are used for spacing
* between components.
*
- * @author Tom Tromey <tromey@redhat.com>
+ * @author Tom Tromey (tromey@redhat.com)
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class FlowLayout implements LayoutManager, Serializable
@@ -69,8 +68,12 @@ public class FlowLayout implements LayoutManager, Serializable
// Serialization constant
private static final long serialVersionUID = -7262534875583282631L;
- /** Add a new component to the layout. This particular implementation
+ /**
+ * Add a new component to the layout. This particular implementation
* does nothing.
+ *
+ * @param name the name
+ * @param comp the component
*/
public void addLayoutComponent (String name, Component comp)
{
diff --git a/libjava/java/awt/Font.java b/libjava/java/awt/Font.java
index 754e078d748..4b2ad5a4f9f 100644
--- a/libjava/java/awt/Font.java
+++ b/libjava/java/awt/Font.java
@@ -38,35 +38,33 @@ exception statement from your version. */
package java.awt;
+import gnu.java.awt.ClasspathToolkit;
+import gnu.java.awt.peer.ClasspathFontPeer;
+
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.LineMetrics;
-import java.awt.font.TextAttribute;
-import java.awt.font.TransformAttribute;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.peer.FontPeer;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.Serializable;
+import java.text.AttributedCharacterIterator;
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
-import java.util.HashMap;
import java.util.StringTokenizer;
-import java.text.CharacterIterator;
-import java.text.AttributedCharacterIterator;
-import java.text.StringCharacterIterator;
-
-import gnu.java.awt.ClasspathToolkit;
-import gnu.java.awt.peer.ClasspathFontPeer;
/**
- * This class represents a windowing system font.
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- * @author Warren Levy <warrenl@cygnus.com>
- * @author Graydon Hoare <graydon@redhat.com>
- */
+ * This class represents a windowing system font.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy (warrenl@cygnus.com)
+ * @author Graydon Hoare (graydon@redhat.com)
+ */
public class Font implements Serializable
{
@@ -163,6 +161,26 @@ public static final int HANGING_BASELINE = 2;
*/
public static final int LAYOUT_NO_LIMIT_CONTEXT = 4;
+ /**
+ * The logical name of this font.
+ *
+ * @since 1.0
+ */
+ protected String name;
+
+ /**
+ * The size of this font in pixels.
+ *
+ * @since 1.0
+ */
+ protected int size;
+
+ /**
+ * The style of this font -- PLAIN, BOLD, ITALIC or BOLD+ITALIC.
+ *
+ * @since 1.0
+ */
+ protected int style;
// Serialization constant
private static final long serialVersionUID = -4206021311591459213L;
@@ -235,7 +253,11 @@ private static final long serialVersionUID = -4206021311591459213L;
size = tokenval;
}
- return getFontFromToolkit (name, attrsToMap (style, size));
+ HashMap attrs = new HashMap();
+ ClasspathFontPeer.copyStyleToAttrs (style, attrs);
+ ClasspathFontPeer.copySizeToAttrs (size, attrs);
+
+ return getFontFromToolkit (name, attrs);
}
/* These methods delegate to the toolkit. */
@@ -245,23 +267,6 @@ private static final long serialVersionUID = -4206021311591459213L;
return (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
}
- protected static Map attrsToMap(int style, int size)
- {
- Map attrs = new HashMap();
- attrs.put (TextAttribute.SIZE, new Float ((float)size));
-
- if ((style & BOLD) == BOLD)
- attrs.put (TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
- else
- attrs.put (TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
-
- if ((style & ITALIC) == ITALIC)
- attrs.put (TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
- else
- attrs.put (TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
- return attrs;
- }
-
/* Every factory method in Font should eventually call this. */
protected static Font getFontFromToolkit (String name, Map attribs)
{
@@ -281,7 +286,7 @@ private static final long serialVersionUID = -4206021311591459213L;
* Returns a <code>Font</code> object from the passed property name.
*
* @param propname The name of the system property.
- * @param default Value to use if the property is not found.
+ * @param defval Value to use if the property is not found.
*
* @return The requested font, or <code>default</code> if the property
* not exist or is malformed.
@@ -326,7 +331,10 @@ private static final long serialVersionUID = -4206021311591459213L;
public Font (String name, int style, int size)
{
- this.peer = getPeerFromToolkit (name, attrsToMap (style, size));
+ HashMap attrs = new HashMap();
+ ClasspathFontPeer.copyStyleToAttrs (style, attrs);
+ ClasspathFontPeer.copySizeToAttrs (size, attrs);
+ this.peer = getPeerFromToolkit (name, attrs);
}
public Font (Map attrs)
@@ -629,7 +637,7 @@ private static final long serialVersionUID = -4206021311591459213L;
* GlyphVector} with a mapped glyph for each input glyph code.
*
* @param ctx The rendering context used for precise glyph placement.
- * @param chars Array of characters to convert to glyphs.
+ * @param glyphCodes Array of characters to convert to glyphs.
*
* @return A new {@link GlyphVector} containing glyphs mapped from str,
* through the font's cmap table.
diff --git a/libjava/java/awt/FontMetrics.java b/libjava/java/awt/FontMetrics.java
index cb76f507909..1520d594993 100644
--- a/libjava/java/awt/FontMetrics.java
+++ b/libjava/java/awt/FontMetrics.java
@@ -38,6 +38,10 @@ exception statement from your version. */
package java.awt;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineMetrics;
+import java.text.CharacterIterator;
+
// FIXME: I leave many methods basically unimplemented. This
// should be reviewed.
@@ -349,6 +353,111 @@ toString()
+ ",descent=" + getDescent() + ",height=" + getHeight() + "]");
}
-} // class FontMetrics
+// Generic FontRenderContext used when getLineMetrics is called with a
+// plain Graphics object.
+private static final FontRenderContext gRC = new FontRenderContext(null,
+ false,
+ false);
+
+/**
+ * Returns a {@link LineMetrics} object constructed with the
+ * specified text and the {@link FontRenderContext} of the Graphics
+ * object when it is an instance of Graphics2D or a generic
+ * FontRenderContext with a null transform, not anti-aliased and not
+ * using fractional metrics.
+ *
+ * @param text The string to calculate metrics from.
+ * @param g The Graphics object that will be used.
+ *
+ * @return A new {@link LineMetrics} object.
+ */
+public LineMetrics getLineMetrics(String text, Graphics g)
+{
+ return getLineMetrics(text, 0, text.length(), g);
+}
+/**
+ * Returns a {@link LineMetrics} object constructed with the
+ * specified text and the {@link FontRenderContext} of the Graphics
+ * object when it is an instance of Graphics2D or a generic
+ * FontRenderContext with a null transform, not anti-aliased and not
+ * using fractional metrics.
+ *
+ * @param text The string to calculate metrics from.
+ * @param begin Index of first character in <code>text</code> to measure.
+ * @param limit Index of last character in <code>text</code> to measure.
+ * @param g The Graphics object that will be used.
+ *
+ * @return A new {@link LineMetrics} object.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>text</code>.
+ */
+public LineMetrics getLineMetrics(String text, int begin,
+ int limit, Graphics g)
+{
+ FontRenderContext rc;
+ if (g instanceof Graphics2D)
+ rc = ((Graphics2D) g).getFontRenderContext();
+ else
+ rc = gRC;
+ return font.getLineMetrics(text, begin, limit, rc);
+}
+
+/**
+ * Returns a {@link LineMetrics} object constructed with the
+ * specified text and the {@link FontRenderContext} of the Graphics
+ * object when it is an instance of Graphics2D or a generic
+ * FontRenderContext with a null transform, not anti-aliased and not
+ * using fractional metrics.
+ *
+ * @param chars The string to calculate metrics from.
+ * @param begin Index of first character in <code>text</code> to measure.
+ * @param limit Index of last character in <code>text</code> to measure.
+ * @param g The Graphics object that will be used.
+ *
+ * @return A new {@link LineMetrics} object.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>text</code>.
+ */
+public LineMetrics getLineMetrics(char[] chars, int begin,
+ int limit, Graphics g)
+{
+ FontRenderContext rc;
+ if (g instanceof Graphics2D)
+ rc = ((Graphics2D) g).getFontRenderContext();
+ else
+ rc = gRC;
+ return font.getLineMetrics(chars, begin, limit, rc);
+}
+
+/**
+ * Returns a {@link LineMetrics} object constructed with the
+ * specified text and the {@link FontRenderContext} of the Graphics
+ * object when it is an instance of Graphics2D or a generic
+ * FontRenderContext with a null transform, not anti-aliased and not
+ * using fractional metrics.
+ *
+ * @param ci An iterator over the string to calculate metrics from.
+ * @param begin Index of first character in <code>text</code> to measure.
+ * @param limit Index of last character in <code>text</code> to measure.
+ * @param g The Graphics object that will be used.
+ *
+ * @return A new {@link LineMetrics} object.
+ *
+ * @throws IndexOutOfBoundsException if the range [begin, limit] is
+ * invalid in <code>text</code>.
+ */
+public LineMetrics getLineMetrics(CharacterIterator ci, int begin,
+ int limit, Graphics g)
+{
+ FontRenderContext rc;
+ if (g instanceof Graphics2D)
+ rc = ((Graphics2D) g).getFontRenderContext();
+ else
+ rc = gRC;
+ return font.getLineMetrics(ci, begin, limit, rc);
+}
+}
diff --git a/libjava/java/awt/Frame.java b/libjava/java/awt/Frame.java
index dd8cdeb00d1..80d2c99ae4d 100644
--- a/libjava/java/awt/Frame.java
+++ b/libjava/java/awt/Frame.java
@@ -39,7 +39,6 @@ exception statement from your version. */
package java.awt;
import java.awt.peer.FramePeer;
-import java.util.Enumeration;
import java.util.Vector;
/**
@@ -199,8 +198,8 @@ private String title = "";
/*
* The number used to generate the name returned by getName.
- */
- private static transient long next_frame_number = 0;
+ */
+ private static transient long next_frame_number;
/**
* Initializes a new instance of <code>Frame</code> that is not visible
@@ -317,6 +316,7 @@ setMenuBar(MenuBar menuBar)
this.menuBar.removeNotify();
if (menuBar != null)
menuBar.addNotify();
+ invalidateTree ();
((FramePeer) peer).setMenuBar(menuBar);
}
this.menuBar = menuBar;
diff --git a/libjava/java/awt/Graphics.java b/libjava/java/awt/Graphics.java
index c75d34e4bc1..8dc703c3274 100644
--- a/libjava/java/awt/Graphics.java
+++ b/libjava/java/awt/Graphics.java
@@ -243,7 +243,7 @@ getClipRect()
* region and the rectangle determined by the specified parameters.
*
* @param x The X coordinate of the upper left corner of the intersect rect.
- * @param Y The Y coordinate of the upper left corner of the intersect rect.
+ * @param y The Y coordinate of the upper left corner of the intersect rect.
* @param width The width of the intersect rect.
* @param height The height of the intersect rect.
*/
@@ -279,7 +279,7 @@ getClip();
/**
* Sets the clipping region to the specified <code>Shape</code>.
*
- * @param shape The new clipping region.
+ * @param clip The new clipping region.
*/
public abstract void
setClip(Shape clip);
@@ -371,7 +371,7 @@ clearRect(int x, int y, int width, int height);
* @param width The width of the draw rect.
* @param height The height of the draw rect.
* @param arcWidth The width of the corner arcs.
- * @param arcHeigth The height of the corner arcs.
+ * @param arcHeight The height of the corner arcs.
*/
public abstract void
drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
@@ -386,7 +386,7 @@ drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
* @param width The width of the fill rect.
* @param height The height of the fill rect.
* @param arcWidth The width of the corner arcs.
- * @param arcHeigth The height of the corner arcs.
+ * @param arcHeight The height of the corner arcs.
*/
public abstract void
fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight);
@@ -480,7 +480,7 @@ fillOval(int x, int y, int width, int height);
* @param arcAngle The extent of the arc.
*/
public abstract void
-drawArc(int x, int y, int width, int height, int startAngle, int arcAngle);
+drawArc(int x, int y, int width, int height, int arcStart, int arcAngle);
/*************************************************************************/
@@ -498,7 +498,7 @@ drawArc(int x, int y, int width, int height, int startAngle, int arcAngle);
* @param arcAngle The extent of the arc.
*/
public abstract void
-fillArc(int x, int y, int width, int height, int startAngle, int arcAngle);
+fillArc(int x, int y, int width, int height, int arcStart, int arcAngle);
/*************************************************************************/
@@ -734,7 +734,7 @@ finalize()
/**
* Returns a string representation of this object.
*
- * @param A string representation of this object.
+ * @return A string representation of this object.
*/
public String
toString()
diff --git a/libjava/java/awt/Graphics2D.java b/libjava/java/awt/Graphics2D.java
index b35f08aa821..e16c2d8fbef 100644
--- a/libjava/java/awt/Graphics2D.java
+++ b/libjava/java/awt/Graphics2D.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002 Free Software Foundation
+/* Copyright (C) 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -34,6 +34,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.awt;
import java.awt.font.FontRenderContext;
@@ -41,12 +42,10 @@ import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
-import java.awt.image.RenderedImage;
import java.awt.image.ImageObserver;
+import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
-
import java.text.AttributedCharacterIterator;
-
import java.util.Map;
/**
diff --git a/libjava/java/awt/GraphicsEnvironment.java b/libjava/java/awt/GraphicsEnvironment.java
index 2b4ce512850..b963f4bab2b 100644
--- a/libjava/java/awt/GraphicsEnvironment.java
+++ b/libjava/java/awt/GraphicsEnvironment.java
@@ -1,5 +1,5 @@
/* GraphicsEnvironment.java -- information about the graphics environment
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,16 +38,17 @@ exception statement from your version. */
package java.awt;
+import gnu.java.awt.ClasspathToolkit;
+
import java.awt.image.BufferedImage;
import java.util.Locale;
-import gnu.java.awt.ClasspathToolkit;
/**
* This descibes the collection of GraphicsDevice and Font objects available
* on a given platform. The resources might be local or remote, and specify
* the valid configurations for displaying graphics.
*
- * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Eric Blake (ebb9@email.byu.edu)
* @see GraphicsDevice
* @see GraphicsConfiguration
* @since 1.4
diff --git a/libjava/java/awt/GridBagConstraints.java b/libjava/java/awt/GridBagConstraints.java
index 651cfdc1999..2795b9ed994 100644
--- a/libjava/java/awt/GridBagConstraints.java
+++ b/libjava/java/awt/GridBagConstraints.java
@@ -1,6 +1,5 @@
-// GridBagConstraints.java - Constraints for GridBag layout manager
-
-/* Copyright (C) 2000, 2001, 2002 Free Software Foundation
+/* GridBagConstraints.java -- Constraints for GridBag layout manager
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -41,8 +40,10 @@ package java.awt;
import java.io.Serializable;
-/** This specifies the constraints for a component managed by the
- * GridBagLayout layout manager. */
+/**
+ * This specifies the constraints for a component managed by the
+ * GridBagLayout layout manager.
+ */
public class GridBagConstraints implements Cloneable, Serializable
{
static final long serialVersionUID = -1000070633030801713L;
diff --git a/libjava/java/awt/GridBagLayout.java b/libjava/java/awt/GridBagLayout.java
index 1239f2cf7f4..85fdfb56eaa 100644
--- a/libjava/java/awt/GridBagLayout.java
+++ b/libjava/java/awt/GridBagLayout.java
@@ -1,5 +1,5 @@
/* GridBagLayout - Layout manager for components according to GridBagConstraints
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,8 +40,8 @@ package java.awt;
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.Hashtable;
import java.util.HashMap;
+import java.util.Hashtable;
/**
* @author Michael Koch <konqueror@gmx.de>
diff --git a/libjava/java/awt/GridLayout.java b/libjava/java/awt/GridLayout.java
index a8befc4c0d3..a9e9eac6629 100644
--- a/libjava/java/awt/GridLayout.java
+++ b/libjava/java/awt/GridLayout.java
@@ -1,6 +1,5 @@
-// GridLayout.java - Grid-based layout engine
-
-/* Copyright (C) 1999, 2000, 2002 Free Software Foundation
+/* GridLayout.java -- Grid-based layout engine
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -63,7 +62,7 @@ public class GridLayout implements LayoutManager, Serializable
/** Add a new component to the layout. This particular implementation
* does nothing.
* @param name The name of the component to add.
- * @param component The component to add.
+ * @param comp The component to add.
*/
public void addLayoutComponent (String name, Component comp)
{
diff --git a/libjava/java/awt/Image.java b/libjava/java/awt/Image.java
index 451b092e6de..37617719b01 100644
--- a/libjava/java/awt/Image.java
+++ b/libjava/java/awt/Image.java
@@ -1,5 +1,5 @@
/* Image.java -- superclass for images
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package java.awt;
-import java.awt.image.AreaAveragingScaleFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
diff --git a/libjava/java/awt/KeyboardFocusManager.java b/libjava/java/awt/KeyboardFocusManager.java
index 3ae4dd6ca85..6fa56d8a88e 100644
--- a/libjava/java/awt/KeyboardFocusManager.java
+++ b/libjava/java/awt/KeyboardFocusManager.java
@@ -1,5 +1,5 @@
/* KeyboardFocusManager.java -- manage component focusing via the keyboard
- Copyright (C) 2002 Free Software Foundation
+ Copyright (C) 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -38,8 +38,8 @@ exception statement from your version. */
package java.awt;
-import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyVetoException;
@@ -55,20 +55,64 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-// FIXME: finish documentation
-
/**
- *
- * FIXME: discuss applet contexts and thread groups and codebases
- * being insulated.
- *
- * FIXME: discuss where default focus traversal key sets apply
- * (inherited by child Components etc.)
+ * The <code>KeyboardFocusManager</code> handles the focusing of
+ * windows for receiving keyboard events. The manager handles
+ * the dispatch of all <code>FocusEvent</code>s and
+ * <code>KeyEvent</code>s, along with <code>WindowEvent</code>s
+ * relating to the focused window. Users can use the manager
+ * to ascertain the current focus owner and fire events.
+ * <br />
+ * <br />
+ * The focus owner is the <code>Component</code> that receives
+ * key events. The focus owner is either the currently focused
+ * window or a component within this window.
+ * <br />
+ * <br />
+ * The underlying native windowing system may denote the active
+ * window or its children with special decorations (e.g. a highlighted
+ * title bar). The active window is always either a <code>Frame</code>
+ * or <code>Dialog</code>, and is either the currently focused
+ * window or its owner.
+ * <br />
+ * <br />
+ * Applets may be partitioned into different applet contexts, according
+ * to their code base. In this case, each context has its own
+ * <code>KeyboardFocusManager</code>, as opposed to the global
+ * manager maintained by applets which share the same context.
+ * Each context is insulated from the others, and they don't interact.
+ * The resulting behaviour, as with context division, depends on the browser
+ * supporting the applets. Regardless, there can only ever be
+ * one focused window, one active window and one focus owner
+ * per <code>ClassLoader</code>.
+ * <br />
+ * <br />
+ * To support this separation of focus managers, the manager instances
+ * and the internal state information is grouped by the
+ * <code>ThreadGroup</code> to which it pertains. With respect to
+ * applets, each code base has its own <code>ThreadGroup</code>, so the
+ * isolation of each context is enforced within the manager.
+ * <br />
+ * <br />
+ * By default, the manager defines TAB and Ctrl+TAB as the
+ * forward focus traversal keys and Shift+TAB and Ctrl+Shift+TAB
+ * as the backward focus traversal keys. No up or down cycle
+ * traversal keys are defined by default. Traversal takes effect
+ * on the firing of a relevant <code>KEY_PRESSED</code> event.
+ * However, all other key events related to the use of the
+ * defined focus traversal key sequence are consumed and not
+ * dispatched.
+ * <br />
+ * <br />
+ * These default traversal keys come into effect on all windows
+ * for which no alternative set of keys is defined. This also
+ * applies recursively to any child components of such a window,
+ * which define no traversal keys of their own.
*
* @author Eric Blake <ebb9@email.byu.edu>
* @author Thomas Fitzsimmons <fitzsim@redhat.com>
+ * @author Andrew John Hughes <gnu_andrew@member.fsf.org>
* @since 1.4
- * @status partially updated to 1.4, needs documentation.
*/
public abstract class KeyboardFocusManager
implements KeyEventDispatcher, KeyEventPostProcessor
@@ -182,7 +226,14 @@ public abstract class KeyboardFocusManager
Collections.EMPTY_SET, Collections.EMPTY_SET
};
+ /**
+ * A utility class to support the handling of events relating to property changes.
+ */
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport (this);
+
+ /**
+ * A utility class to support the handling of events relating to vetoable changes.
+ */
private final VetoableChangeSupport vetoableChangeSupport = new VetoableChangeSupport (this);
/** A list of {@link KeyEventDispatcher}s that process {@link
@@ -211,6 +262,10 @@ public abstract class KeyboardFocusManager
public static KeyboardFocusManager getCurrentKeyboardFocusManager ()
{
ThreadGroup currentGroup = Thread.currentThread ().getThreadGroup ();
+
+ if (currentKeyboardFocusManagers.get (currentGroup) == null)
+ setCurrentKeyboardFocusManager (null);
+
return (KeyboardFocusManager) currentKeyboardFocusManagers.get (currentGroup);
}
@@ -623,29 +678,99 @@ public abstract class KeyboardFocusManager
setGlobalObject (currentFocusCycleRoots, cycleRoot, "currentFocusCycleRoot");
}
+ /**
+ * Registers the supplied property change listener for receiving
+ * events caused by the following property changes:
+ *
+ * <ul>
+ * <li>the current focus owner ("focusOwner")</li>
+ * <li>the permanent focus owner ("permanentFocusOwner")</li>
+ * <li>the focused window ("focusedWindow")</li>
+ * <li>the active window ("activeWindow")</li>
+ * <li>the default focus traversal policy ("defaultFocusTraversalPolicy")</li>
+ * <li>the default set of forward traversal keys ("forwardDefaultFocusTraversalKeys")</li>
+ * <li>the default set of backward traversal keys ("backwardDefaultFocusTraversalKeys")</li>
+ * <li>the default set of up cycle traversal keys ("upCycleDefaultFocusTraversalKeys")</li>
+ * <li>the default set of down cycle traversal keys ("downCycleDefaultFocusTraversalKeys")</li>
+ * <li>the current focus cycle root ("currentFocusCycleRoot")</li>
+ * </ul>
+ *
+ * If the supplied listener is null, nothing occurs.
+ *
+ * @param l the new listener to register.
+ * @see KeyboardFocusManager#addPropertyChangeListener(String, java.beans.PropertyChangeListener)
+ */
public void addPropertyChangeListener(PropertyChangeListener l)
{
if (l != null)
propertyChangeSupport.addPropertyChangeListener(l);
}
+ /**
+ * Removes the supplied property change listener from the list
+ * of registered listeners. If the supplied listener is null,
+ * nothing occurs.
+ *
+ * @param l the listener to remove.
+ */
public void removePropertyChangeListener(PropertyChangeListener l)
{
if (l != null)
propertyChangeSupport.removePropertyChangeListener(l);
}
+ /**
+ * Returns the currently registered property change listeners
+ * in array form. The returned array is empty if no listeners are
+ * currently registered.
+ *
+ * @return an array of registered property change listeners.
+ */
public PropertyChangeListener[] getPropertyChangeListeners()
{
return propertyChangeSupport.getPropertyChangeListeners();
}
+ /**
+ * Registers a property change listener for receiving events relating
+ * to a change to a specified property. The supplied property name can be
+ * either user-defined or one from the following list of properties
+ * relevant to this class:
+ *
+ * <ul>
+ * <li>the current focus owner ("focusOwner")</li>
+ * <li>the permanent focus owner ("permanentFocusOwner")</li>
+ * <li>the focused window ("focusedWindow")</li>
+ * <li>the active window ("activeWindow")</li>
+ * <li>the default focus traversal policy ("defaultFocusTraversalPolicy")</li>
+ * <li>the default set of forward traversal keys ("forwardDefaultFocusTraversalKeys")</li>
+ * <li>the default set of backward traversal keys ("backwardDefaultFocusTraversalKeys")</li>
+ * <li>the default set of up cycle traversal keys ("upCycleDefaultFocusTraversalKeys")</li>
+ * <li>the default set of down cycle traversal keys ("downCycleDefaultFocusTraversalKeys")</li>
+ * <li>the current focus cycle root ("currentFocusCycleRoot")</li>
+ * </ul>
+ *
+ * Nothing occurs if a null listener is supplied. null is regarded as a valid property name.
+ *
+ * @param name the name of the property to handle change events for.
+ * @param l the listener to register for changes to the specified property.
+ * @see KeyboardFocusManager#addPropertyChangeListener(java.beans.PropertyChangeListener)
+ */
public void addPropertyChangeListener(String name, PropertyChangeListener l)
{
if (l != null)
propertyChangeSupport.addPropertyChangeListener(name, l);
}
+ /**
+ * Removes the supplied property change listener registered for the
+ * specified property from the list of registered listeners. If the
+ * supplied listener is null, nothing occurs.
+ *
+ * @param name the name of the property the listener is
+ * monitoring changes to.
+ * @param l the listener to remove.
+ */
public void removePropertyChangeListener(String name,
PropertyChangeListener l)
{
@@ -653,39 +778,117 @@ public abstract class KeyboardFocusManager
propertyChangeSupport.removePropertyChangeListener(name, l);
}
+ /**
+ * Returns the currently registered property change listeners
+ * in array form, which listen for changes to the supplied property.
+ * The returned array is empty, if no listeners are currently registered
+ * for events pertaining to the supplied property.
+ *
+ * @param name The property the returned listeners monitor for changes.
+ * @return an array of registered property change listeners which
+ * listen for changes to the supplied property.
+ */
public PropertyChangeListener[] getPropertyChangeListeners(String name)
{
return propertyChangeSupport.getPropertyChangeListeners(name);
}
+ /**
+ * Fires a property change event as a response to a change to
+ * to the specified property. The event is only fired if a
+ * change has actually occurred (i.e. o and n are different).
+ *
+ * @param name The name of the property to which a change occurred.
+ * @param o The old value of the property.
+ * @param n The new value of the property.
+ */
protected void firePropertyChange(String name, Object o, Object n)
{
propertyChangeSupport.firePropertyChange(name, o, n);
}
+ /**
+ * Registers a vetoable property change listener for receiving events
+ * relating to the following properties:
+ *
+ * <ul>
+ * <li>the current focus owner ("focusOwner")</li>
+ * <li>the permanent focus owner ("permanentFocusOwner")</li>
+ * <li>the focused window ("focusedWindow")</li>
+ * <li>the active window ("activeWindow")</li>
+ * </ul>
+ *
+ * Nothing occurs if a null listener is supplied.
+ *
+ * @param l the listener to register.
+ * @see KeyboardFocusManager#addVetoableChangeListener(String, java.beans.VetoableChangeListener)
+ */
public void addVetoableChangeListener(VetoableChangeListener l)
{
if (l != null)
vetoableChangeSupport.addVetoableChangeListener(l);
}
+ /**
+ * Removes the supplied vetoable property change listener from
+ * the list of registered listeners. If the supplied listener
+ * is null, nothing occurs.
+ *
+ * @param l the listener to remove.
+ */
public void removeVetoableChangeListener(VetoableChangeListener l)
{
if (l != null)
vetoableChangeSupport.removeVetoableChangeListener(l);
}
+ /**
+ * Returns the currently registered vetoable property change listeners
+ * in array form. The returned array is empty if no listeners are
+ * currently registered.
+ *
+ * @return an array of registered vetoable property change listeners.
+ * @since 1.4
+ */
public VetoableChangeListener[] getVetoableChangeListeners()
{
return vetoableChangeSupport.getVetoableChangeListeners();
}
+ /**
+ * Registers a vetoable property change listener for receiving events relating
+ * to a vetoable change to a specified property. The supplied property name can be
+ * either user-defined or one from the following list of properties
+ * relevant to this class:
+ *
+ * <ul>
+ * <li>the current focus owner ("focusOwner")</li>
+ * <li>the permanent focus owner ("permanentFocusOwner")</li>
+ * <li>the focused window ("focusedWindow")</li>
+ * <li>the active window ("activeWindow")</li>
+ * </ul>
+ *
+ * Nothing occurs if a null listener is supplied. null is regarded as a valid property name.
+ *
+ * @param name the name of the property to handle change events for.
+ * @param l the listener to register for changes to the specified property.
+ * @see KeyboardFocusManager#addVetoableChangeListener(java.beans.VetoableChangeListener)
+ */
public void addVetoableChangeListener(String name, VetoableChangeListener l)
{
if (l != null)
vetoableChangeSupport.addVetoableChangeListener(name, l);
}
+ /**
+ * Removes the supplied vetoable property change listener registered
+ * for the specified property from the list of registered listeners.
+ * If the supplied listener is null, nothing occurs.
+ *
+ * @param name the name of the vetoable property the listener is
+ * monitoring changes to.
+ * @param l the listener to remove.
+ */
public void removeVetoableChangeListener(String name,
VetoableChangeListener l)
{
@@ -693,51 +896,210 @@ public abstract class KeyboardFocusManager
vetoableChangeSupport.removeVetoableChangeListener(name, l);
}
+ /**
+ * Returns the currently registered vetoable property change listeners
+ * in array form, which listen for changes to the supplied property.
+ * The returned array is empty, if no listeners are currently registered
+ * for events pertaining to the supplied property.
+ *
+ * @param name The property the returned listeners monitor for changes.
+ * @return an array of registered property change listeners which
+ * listen for changes to the supplied property.
+ * @since 1.4
+ */
public VetoableChangeListener[] getVetoableChangeListeners(String name)
{
return vetoableChangeSupport.getVetoableChangeListeners(name);
}
+ /**
+ * Fires a property change event as a response to a vetoable change to
+ * to the specified property. The event is only fired if a
+ * change has actually occurred (i.e. o and n are different).
+ * In the event that the property change is vetoed, the following
+ * occurs:
+ *
+ * <ol>
+ * <li>
+ * This method throws a <code>PropertyVetoException</code> to
+ * the proposed change.
+ * </li>
+ * <li>
+ * A new event is fired to reverse the previous change.
+ * </li>
+ * <li>
+ * This method again throws a <code>PropertyVetoException</code>
+ * in response to the reversion.
+ * </li>
+ * </ol>
+ *
+ * @param name The name of the property to which a change occurred.
+ * @param o The old value of the property.
+ * @param n The new value of the property.
+ * @throws PropertyVetoException if one of the listeners vetos
+ * the change by throwing this exception.
+ */
protected void fireVetoableChange(String name, Object o, Object n)
throws PropertyVetoException
{
vetoableChangeSupport.fireVetoableChange(name, o, n);
}
+ /**
+ * Adds a key event dispatcher to the list of registered dispatchers.
+ * When a key event is fired, each dispatcher's <code>dispatchKeyEvent</code>
+ * method is called in the order that they were added, prior to the manager
+ * dispatching the event itself. Notifications halt when one of the
+ * dispatchers returns true.
+ * <br />
+ * <br />
+ * The same dispatcher can exist multiple times within the list
+ * of registered dispatchers, and there is no limit on the length
+ * of this list. A null dispatcher is simply ignored.
+ *
+ * @param dispatcher The dispatcher to register.
+ */
public void addKeyEventDispatcher(KeyEventDispatcher dispatcher)
{
if (dispatcher != null)
keyEventDispatchers.add(dispatcher);
}
+ /**
+ * Removes the specified key event dispatcher from the list of
+ * registered dispatchers. The manager always dispatches events,
+ * regardless of its existence within the list. The manager
+ * can be added and removed from the list, as with any other
+ * dispatcher, but this does not affect its ability to dispatch
+ * key events. Non-existent and null dispatchers are simply ignored
+ * by this method.
+ *
+ * @param dispatcher The dispatcher to remove.
+ */
public void removeKeyEventDispatcher(KeyEventDispatcher dispatcher)
{
keyEventDispatchers.remove(dispatcher);
}
+ /**
+ * Returns the currently registered key event dispatchers in <code>List</code>
+ * form. At present, this only includes dispatchers explicitly registered
+ * via the <code>addKeyEventDispatcher()</code> method, but this behaviour
+ * is subject to change and should not be depended on. The manager itself
+ * may be a member of the list, but only if explicitly registered. If no
+ * dispatchers have been registered, the list will be empty.
+ *
+ * @return A list of explicitly registered key event dispatchers.
+ * @see KeyboardFocusManager#addKeyEventDispatcher(java.awt.KeyEventDispatcher)
+ */
protected List getKeyEventDispatchers ()
{
return (List) keyEventDispatchers.clone ();
}
+ /**
+ * Adds a key event post processor to the list of registered post processors.
+ * Post processors work in the same way as key event dispatchers, except
+ * that they are invoked after the manager has dispatched the key event,
+ * and not prior to this. Each post processor's <code>postProcessKeyEvent</code>
+ * method is called to see if any post processing needs to be performed. THe
+ * processors are called in the order in which they were added to the list,
+ * and notifications continue until one returns true. As with key event
+ * dispatchers, the manager is implicitly called following this process,
+ * regardless of whether or not it is present within the list.
+ * <br />
+ * <br />
+ * The same post processor can exist multiple times within the list
+ * of registered post processors, and there is no limit on the length
+ * of this list. A null post processor is simply ignored.
+ *
+ * @param postProcessor the post processor to register.
+ * @see KeyboardFocusManager#addKeyEventDispatcher(java.awt.KeyEventDispatcher)
+ */
public void addKeyEventPostProcessor (KeyEventPostProcessor postProcessor)
{
if (postProcessor != null)
keyEventPostProcessors.add (postProcessor);
}
+ /**
+ * Removes the specified key event post processor from the list of
+ * registered post processors. The manager always post processes events,
+ * regardless of its existence within the list. The manager
+ * can be added and removed from the list, as with any other
+ * post processor, but this does not affect its ability to post process
+ * key events. Non-existent and null post processors are simply ignored
+ * by this method.
+ *
+ * @param postProcessor the post processor to remove.
+ */
public void removeKeyEventPostProcessor (KeyEventPostProcessor postProcessor)
{
keyEventPostProcessors.remove (postProcessor);
}
+ /**
+ * Returns the currently registered key event post processors in <code>List</code>
+ * form. At present, this only includes post processors explicitly registered
+ * via the <code>addKeyEventPostProcessor()</code> method, but this behaviour
+ * is subject to change and should not be depended on. The manager itself
+ * may be a member of the list, but only if explicitly registered. If no
+ * post processors have been registered, the list will be empty.
+ *
+ * @return A list of explicitly registered key event post processors.
+ * @see KeyboardFocusManager#addKeyEventPostProcessor(java.awt.KeyEventPostProcessor)
+ */
protected List getKeyEventPostProcessors ()
{
return (List) keyEventPostProcessors.clone ();
}
+ /**
+ * The AWT event dispatcher uses this method to request that the manager
+ * handle a particular event. If the manager fails or refuses to
+ * dispatch the supplied event (this method returns false), the
+ * AWT event dispatcher will try to dispatch the event itself.
+ * <br />
+ * <br />
+ * The manager is expected to handle all <code>FocusEvent</code>s
+ * and <code>KeyEvent</code>s, and <code>WindowEvent</code>s
+ * relating to the focus. Dispatch is done with regard to the
+ * the focus owner and the currently focused and active windows.
+ * In handling the event, the source of the event may be overridden.
+ * <br />
+ * <br />
+ * The actual dispatching is performed by calling
+ * <code>redispatchEvent()</code>. This avoids the infinite recursion
+ * of dispatch requests which may occur if this method is called on
+ * the target component.
+ *
+ * @param e the event to dispatch.
+ * @return true if the event was dispatched.
+ * @see KeyboardFocusManager#redispatchEvent(java.awt.Component, java.awt.AWTEvent)
+ * @see KeyEvent
+ * @see FocusEvent
+ * @see WindowEvent
+ */
public abstract boolean dispatchEvent (AWTEvent e);
+ /**
+ * Handles redispatching of an event so that recursion of
+ * dispatch requests does not occur. Event dispatch methods
+ * within this manager (<code>dispatchEvent()</code>) and
+ * the key event dispatchers should use this method to handle
+ * dispatching rather than the dispatch method of the target
+ * component.
+ * <br />
+ * <br />
+ * <strong>
+ * This method is not intended for general consumption, and is
+ * only for the use of the aforementioned classes.
+ * </strong>
+ *
+ * @param target the target component to which the event is
+ * dispatched.
+ * @param e the event to dispatch.
+ */
public final void redispatchEvent (Component target, AWTEvent e)
{
synchronized (e)
@@ -747,42 +1109,203 @@ public abstract class KeyboardFocusManager
}
}
+ /**
+ * Attempts to dispatch key events for which no key event dispatcher
+ * has so far succeeded. This method is usually called by
+ * <code>dispatchEvent()</code> following the sending of the key
+ * event to any registered key event dispatchers. If the key
+ * event reaches this stage, none of the dispatchers returned
+ * true. This is, of course, always the case if there are no
+ * registered dispatchers.
+ * <br />
+ * <br />
+ * If this method also fails to handle the key event, then
+ * false is returned to the caller. In the case of
+ * <code>dispatchEvent()</code>, the calling method may try
+ * to handle the event itself or simply forward on the
+ * false result to its caller. When the event is dispatched
+ * by this method, a true result is propogated through the
+ * calling methods.
+ *
+ * @param e the key event to dispatch.
+ * @return true if the event was dispatched successfully.
+ */
public abstract boolean dispatchKeyEvent (KeyEvent e);
+ /**
+ * Handles the post processing of key events. By default,
+ * this method will map unhandled key events to appropriate
+ * <code>MenuShortcut</code>s. The event is consumed
+ * in the process and the shortcut is activated. This
+ * method is usually called by <code>dispatchKeyEvent</code>.
+ *
+ * @param e the key event to post process.
+ * @return true by default, as the event was handled.
+ */
public abstract boolean postProcessKeyEvent (KeyEvent e);
+ /**
+ * Handles focus traversal operations for key events which
+ * represent focus traversal keys in relation to the supplied
+ * component. The supplied component is assumed to have the
+ * focus, whether it does so or not, and the operation is
+ * carried out as appropriate, with this in mind.
+ *
+ * @param focused the component on which to perform focus traversal,
+ * on the assumption that this component has the focus.
+ * @param e the possible focus traversal key event.
+ */
public abstract void processKeyEvent (Component focused, KeyEvent e);
+ /**
+ * Delays all key events following the specified timestamp until the
+ * supplied component has focus. The AWT calls this method when it is
+ * determined that a focus change may occur within the native windowing
+ * system. Any key events which occur following the time specified by
+ * after are delayed until a <code>FOCUS_GAINED</code> event is received
+ * for the untilFocused component. The manager is responsible for ensuring
+ * this takes place.
+ *
+ * @param after the timestamp beyond which all key events are delayed until
+ * the supplied component gains focus.
+ * @param untilFocused the component to wait on gaining focus.
+ */
protected abstract void enqueueKeyEvents (long after, Component untilFocused);
+ /**
+ * Removes the key event block specified by the supplied timestamp and component.
+ * All delayed key events are released for normal dispatching following its
+ * removal and subsequent key events that would have been blocked are now
+ * immediately dispatched. If the specified timestamp is below 0, then
+ * the request with the oldest timestamp is removed.
+ *
+ * @param after the timestamp of the key event block to be removed, or a
+ * value smaller than 0 if the oldest is to be removed.
+ * @param untilFocused the component of the key event block to be removed.
+ */
protected abstract void dequeueKeyEvents (long after, Component untilFocused);
+ /**
+ * Discards all key event blocks relating to focus requirements for
+ * the supplied component, regardless of timestamp.
+ *
+ * @param comp the component of the key event block(s) to be removed.
+ */
protected abstract void discardKeyEvents (Component comp);
- public abstract void focusNextComponent (Component comp);
+ /**
+ * Moves the current focus to the next component following
+ * comp, based on the current focus traversal policy. By
+ * default, only visible, displayable, accepted components
+ * can receive focus. <code>Canvas</code>es, <code>Panel</code>s,
+ * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
+ * <code>Window</code>s and lightweight components are judged
+ * to be unacceptable by default. See the
+ * <code>DefaultFocusTraversalPolicy</code> for more details.
+ *
+ * @param comp the component prior to the one which will
+ * become the focus, following execution of this method.
+ * @see DefaultFocusTraversalPolicy
+ */
+ public abstract void focusNextComponent(Component comp);
- public abstract void focusPreviousComponent (Component comp);
+ /**
+ * Moves the current focus to the previous component, prior to
+ * comp, based on the current focus traversal policy. By
+ * default, only visible, displayable, accepted components
+ * can receive focus. <code>Canvas</code>es, <code>Panel</code>s,
+ * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
+ * <code>Window</code>s and lightweight components are judged
+ * to be unacceptable by default. See the
+ * <code>DefaultFocusTraversalPolicy</code> for more details.
+ *
+ * @param comp the component following the one which will
+ * become the focus, following execution of this method.
+ * @see DefaultFocusTraversalPolicy
+ */
+ public abstract void focusPreviousComponent(Component comp);
- public abstract void upFocusCycle (Component comp);
+ /**
+ * Moves the current focus upwards by one focus cycle.
+ * Both the current focus owner and current focus cycle root
+ * become the focus cycle root of the supplied component.
+ * However, in the case of a <code>Window</code>, the default
+ * focus component becomes the focus owner and the focus cycle
+ * root is not changed.
+ *
+ * @param comp the component used as part of the focus traversal.
+ */
+ public abstract void upFocusCycle(Component comp);
- public abstract void downFocusCycle (Container cont);
+ /**
+ * Moves the current focus downwards by one focus cycle.
+ * If the supplied container is a focus cycle root, then this
+ * becomes the current focus cycle root and the focus goes
+ * to the default component of the specified container.
+ * Nothing happens for non-focus cycle root containers.
+ *
+ * @param cont the container used as part of the focus traversal.
+ */
+ public abstract void downFocusCycle(Container cont);
- public final void focusNextComponent ()
+ /**
+ * Moves the current focus to the next component, based on the
+ * current focus traversal policy. By default, only visible,
+ * displayable, accepted component can receive focus.
+ * <code>Canvas</code>es, <code>Panel</code>s,
+ * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
+ * <code>Window</code>s and lightweight components are judged
+ * to be unacceptable by default. See the
+ * <code>DefaultFocusTraversalPolicy</code> for more details.
+ *
+ * @see DefaultFocusTraversalPolicy
+ */
+ public final void focusNextComponent()
{
focusNextComponent (null);
}
- public final void focusPreviousComponent ()
+ /**
+ * Moves the current focus to the previous component, based on the
+ * current focus traversal policy. By default, only visible,
+ * displayable, accepted component can receive focus.
+ * <code>Canvas</code>es, <code>Panel</code>s,
+ * <code>Label</code>s, <code>ScrollPane</code>s, <code>Scrollbar</code>s,
+ * <code>Window</code>s and lightweight components are judged
+ * to be unacceptable by default. See the
+ * <code>DefaultFocusTraversalPolicy</code> for more details.
+ *
+ * @see DefaultFocusTraversalPolicy
+ */
+ public final void focusPreviousComponent()
{
focusPreviousComponent (null);
}
- public final void upFocusCycle ()
+ /**
+ * Moves the current focus upwards by one focus cycle,
+ * so that the new focus owner is the focus cycle root
+ * of the current owner. The current focus cycle root then
+ * becomes the focus cycle root of the new focus owner.
+ * However, in the case of the focus cycle root of the
+ * current focus owner being a <code>Window</code>, the default
+ * component of this window becomes the focus owner and the
+ * focus cycle root is not changed.
+ */
+ public final void upFocusCycle()
{
upFocusCycle (null);
}
- public final void downFocusCycle ()
+ /**
+ * Moves the current focus downwards by one focus cycle,
+ * iff the current focus cycle root is a <code>Container</code>.
+ * Usually, the new focus owner is set to the default component
+ * of the container and the current focus cycle root is set
+ * to the current focus owner. Nothing occurs if the current
+ * focus cycle root is not a container.
+ */
+ public final void downFocusCycle()
{
Component focusOwner = getGlobalFocusOwner ();
if (focusOwner instanceof Container
diff --git a/libjava/java/awt/Label.java b/libjava/java/awt/Label.java
index 37ff4ec5bd1..189bc10a756 100644
--- a/libjava/java/awt/Label.java
+++ b/libjava/java/awt/Label.java
@@ -1,5 +1,5 @@
/* Label.java -- Java label widget
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,14 +39,18 @@ exception statement from your version. */
package java.awt;
import java.awt.peer.LabelPeer;
+
import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
/**
* This component is used for displaying simple text strings that cannot
- * be edited.
+ * be edited by the user.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey <tromey@cygnus.com>
+ * @author Andrew John Hughes <gnu_andrew@member.fsf.org>
*/
public class Label extends Component implements Accessible
{
@@ -240,7 +244,7 @@ addNotify()
/**
* Returns a parameter string useful for debugging.
*
- * @param A debugging string.
+ * @return A debugging string.
*/
protected String
paramString()
@@ -249,5 +253,65 @@ paramString()
getAlignment() + "," + super.paramString());
}
+/**
+ * This class provides accessibility support for the label.
+ */
+protected class AccessibleAWTLabel
+ extends AccessibleAWTComponent
+{
+ /**
+ * For compatability with Sun's JDK 1.4.2 rev. 5
+ */
+ private static final long serialVersionUID = -3568967560160480438L;
+
+ /**
+ * Constructor for the accessible label.
+ */
+ public AccessibleAWTLabel()
+ {
+ }
+
+ /**
+ * Returns the accessible name for the label. This is
+ * the text used in the label.
+ *
+ * @return a <code>String</code> containing the accessible
+ * name for this label.
+ */
+ public String getAccessibleName()
+ {
+ return getText();
+ }
+
+ /**
+ * Returns the accessible role for the label.
+ *
+ * @return an instance of <code>AccessibleRole</code>, describing
+ * the role of the label.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.LABEL;
+ }
+
+}
+
+/**
+ * Gets the AccessibleContext associated with this <code>Label</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+public AccessibleContext getAccessibleContext()
+{
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ {
+ /* Create the context */
+ accessibleContext = new AccessibleAWTLabel();
+ }
+ return accessibleContext;
+}
+
} // class Label
diff --git a/libjava/java/awt/LayoutManager2.java b/libjava/java/awt/LayoutManager2.java
index 802e25e664b..4caa7f2cff2 100644
--- a/libjava/java/awt/LayoutManager2.java
+++ b/libjava/java/awt/LayoutManager2.java
@@ -42,7 +42,7 @@ package java.awt;
* Layout manager for laying out containers based on contraints. The
* constraints control how the layout will proceed.
*
- * @author Aaron M. Renn <arenn@urbanophile.com>
+ * @author Aaron M. Renn (arenn@urbanophile.com)
* @see LayoutManager
* @see Container
* @since 1.0
@@ -57,7 +57,7 @@ public interface LayoutManager2 extends LayoutManager
* @param component the component to add
* @param constraints the constraints to satisfy
*/
- void addLayoutComponent(Component component, Object contraints);
+ void addLayoutComponent(Component component, Object constraints);
/**
* Determines the maximum size of the specified target container.
diff --git a/libjava/java/awt/List.java b/libjava/java/awt/List.java
index 47177edc7a0..8fbbc07720e 100644
--- a/libjava/java/awt/List.java
+++ b/libjava/java/awt/List.java
@@ -1,5 +1,5 @@
/* List.java -- A listbox widget
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -45,6 +45,7 @@ import java.awt.event.ItemListener;
import java.awt.peer.ListPeer;
import java.util.EventListener;
import java.util.Vector;
+
import javax.accessibility.Accessible;
/**
@@ -129,7 +130,7 @@ List()
* Initializes a new instance of <code>List</code> with the specified
* number of visible lines and multi-select disabled.
*
- * @param lines The number of visible lines in the list.
+ * @param rows The number of visible rows in the list.
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
*/
@@ -145,7 +146,7 @@ List(int rows)
* Initializes a new instance of <code>List</code> with the specified
* number of lines and the specified multi-select setting.
*
- * @param lines The number of visible lines in the list.
+ * @param rows The number of visible rows in the list.
* @param multipleMode <code>true</code> if multiple lines can be selected
* simultaneously, <code>false</code> otherwise.
*
diff --git a/libjava/java/awt/MediaTracker.java b/libjava/java/awt/MediaTracker.java
index d1df8b38360..e69832d11a0 100644
--- a/libjava/java/awt/MediaTracker.java
+++ b/libjava/java/awt/MediaTracker.java
@@ -1,5 +1,5 @@
/* MediaTracker.java -- Class used for keeping track of images
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002i, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,8 @@ exception statement from your version. */
package java.awt;
-import java.util.ArrayList;
import java.awt.image.ImageObserver;
+import java.util.ArrayList;
/**
* This class is used for keeping track of the status of various media
diff --git a/libjava/java/awt/Menu.java b/libjava/java/awt/Menu.java
index c6c4f214dce..35798a066df 100644
--- a/libjava/java/awt/Menu.java
+++ b/libjava/java/awt/Menu.java
@@ -40,8 +40,11 @@ package java.awt;
import java.awt.peer.MenuPeer;
import java.io.Serializable;
-import java.util.Vector;
import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
/**
* This class represents a pull down or tear off menu in Java's AWT.
@@ -72,17 +75,20 @@ private Vector items = new Vector();
/**
* @serial Flag indicating whether or not this menu is a tear off
*/
-private boolean isTearOff;
+private boolean tearOff;
/**
* @serial Indicates whether or not this is a help menu.
*/
private boolean isHelpMenu;
-// From the serialization spec. FIXME: what should it be?
-private int menuSerializedDataVersion;
+ /*
+ * @serial Unused in this implementation, but present in Sun's
+ * serialization spec. Value obtained via reflection.
+ */
+ private int menuSerializedDataVersion = 1;
-static final String separatorLabel = "-";
+static final transient String separatorLabel = "-";
/*************************************************************************/
@@ -134,7 +140,7 @@ Menu(String label, boolean isTearOff)
{
super(label);
- this.isTearOff = isTearOff;
+ tearOff = isTearOff;
if (label.equals("Help"))
isHelpMenu = true;
@@ -158,7 +164,7 @@ Menu(String label, boolean isTearOff)
public boolean
isTearOff()
{
- return(isTearOff);
+ return(tearOff);
}
/*************************************************************************/
@@ -251,8 +257,6 @@ add(String label)
* @param item The menu item to add.
* @param index The index of the menu item.
*
- * XXX: FIXME
- *
* @exception IllegalArgumentException If the index is less than zero.
* @exception ArrayIndexOutOfBoundsException If the index is otherwise invalid.
*/
@@ -262,12 +266,26 @@ insert(MenuItem item, int index)
if (index < 0)
throw new IllegalArgumentException("Index is less than zero");
- items.insertElementAt(item, index);
+ MenuPeer peer = (MenuPeer) getPeer();
+ if (peer == null)
+ return;
- MenuPeer mp = (MenuPeer)getPeer();
- // FIXME: Need to add a peer method here.
-// if (mp != null)
-// mp.insertItem(item, index);
+ int count = getItemCount ();
+
+ if (index >= count)
+ peer.addItem (item);
+ else
+ {
+ for (int i = count - 1; i >= index; i--)
+ peer.delItem (i);
+
+ peer.addItem (item);
+
+ for (int i = index; i < count; i++)
+ peer.addItem ((MenuItem) items.elementAt (i));
+ }
+
+ items.insertElementAt(item, index);
}
/*************************************************************************/
@@ -305,8 +323,6 @@ addSeparator()
*
* @param index The index at which to insert a separator bar.
*
- * XXX: FIXME
- *
* @exception IllegalArgumentException If the index is less than zero.
* @exception ArrayIndexOutOfBoundsException If the index is otherwise invalid.
*/
@@ -339,7 +355,7 @@ remove(int index)
/**
* Removes the specifed item from the menu. If the specified component
- * does not exist, this method does nothing. // FIXME: Right?
+ * does not exist, this method does nothing.
*
* @param item The component to remove.
*/
@@ -415,11 +431,32 @@ removeNotify()
public String
paramString()
{
- return (",isTearOff=" + isTearOff + ",isHelpMenu=" + isHelpMenu
+ return (",tearOff=" + tearOff + ",isHelpMenu=" + isHelpMenu
+ super.paramString());
}
-// Accessibility API not yet implemented.
-// public AccessibleContext getAccessibleContext()
+ /**
+ * Basic Accessibility class for Menu. Details get provided in derived
+ * classes.
+ */
+ protected class AccessibleAWTMenu extends AccessibleAWTMenuItem
+ {
+ protected AccessibleAWTMenu()
+ {
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.MENU;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.MenuComponent#getAccessibleContext()
+ */
+ public AccessibleContext getAccessibleContext()
+ {
+ return new AccessibleAWTMenu();
+ }
} // class Menu
diff --git a/libjava/java/awt/MenuBar.java b/libjava/java/awt/MenuBar.java
index 1c9b1c78946..6a97fa95685 100644
--- a/libjava/java/awt/MenuBar.java
+++ b/libjava/java/awt/MenuBar.java
@@ -45,14 +45,19 @@ import java.io.Serializable;
import java.util.Enumeration;
import java.util.Vector;
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
/**
* This class implements a menu bar in the AWT system.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
* @author Tom Tromey <tromey@redhat.com>
+ * @author Andrew John Hughes <gnu_andrew@member.fsf.org>
*/
public class MenuBar extends MenuComponent
- implements MenuContainer, Serializable
+ implements MenuContainer, Serializable, Accessible
{
/*
@@ -78,6 +83,14 @@ private Menu helpMenu;
*/
private Vector menus = new Vector();
+ /**
+ * The accessible context for this component.
+ *
+ * @see #getAccessibleContext()
+ * @serial ignored.
+ */
+ private transient AccessibleContext accessibleContext;
+
/*************************************************************************/
/*
@@ -118,7 +131,7 @@ getHelpMenu()
/**
* Sets the help menu for this menu bar.
*
- * @param helpMenu The new help menu for this menu bar.
+ * @param menu The new help menu for this menu bar.
*/
public synchronized void
setHelpMenu(Menu menu)
@@ -134,11 +147,11 @@ setHelpMenu(Menu menu)
menu.parent.remove (menu);
menu.parent = this;
+ MenuBarPeer peer = (MenuBarPeer) getPeer ();
if (peer != null)
{
menu.addNotify();
- MenuBarPeer mp = (MenuBarPeer) peer;
- mp.addHelpMenu (menu);
+ peer.addHelpMenu (menu);
}
}
@@ -233,8 +246,7 @@ getMenuCount()
public int
countMenus()
{
- // FIXME: How does the help menu fit in here?
- return menus.size ();
+ return menus.size () + (getHelpMenu () == null ? 0 : 1);
}
/*************************************************************************/
@@ -242,6 +254,8 @@ countMenus()
/**
* Returns the menu at the specified index.
*
+ * @param index the index of the menu
+ *
* @return The requested menu.
*
* @exception ArrayIndexOutOfBoundsException If the index is not valid.
@@ -357,4 +371,56 @@ deleteShortcut(MenuShortcut shortcut)
it.deleteShortcut ();
}
+/**
+ * Gets the AccessibleContext associated with this <code>MenuBar</code>.
+ * The context is created, if necessary.
+ *
+ * @return the associated context
+ */
+public AccessibleContext getAccessibleContext()
+{
+ /* Create the context if this is the first request */
+ if (accessibleContext == null)
+ {
+ /* Create the context */
+ accessibleContext = new AccessibleAWTMenuBar();
+ }
+ return accessibleContext;
+}
+
+/**
+ * This class provides accessibility support for AWT menu bars.
+ *
+ * @author Andrew John Hughes <gnu_andrew@member.fsf.org>
+ */
+protected class AccessibleAWTMenuBar
+ extends AccessibleAWTMenuComponent
+{
+
+ /**
+ * Compatible with JDK 1.4.2 revision 5
+ */
+ private static final long serialVersionUID = -8577604491830083815L;
+
+ /**
+ * This is the default constructor, which simply calls the default
+ * constructor of the superclass.
+ */
+ protected AccessibleAWTMenuBar()
+ {
+ super();
+ }
+
+ /**
+ * Returns the accessible role relating to the menu bar.
+ *
+ * @return <code>AccessibleRole.MENU_BAR</code>.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.MENU_BAR;
+ }
+
+} // class AccessibleAWTMenuBar
+
} // class MenuBar
diff --git a/libjava/java/awt/MenuComponent.java b/libjava/java/awt/MenuComponent.java
index ccf2b497443..78adfaea6e3 100644
--- a/libjava/java/awt/MenuComponent.java
+++ b/libjava/java/awt/MenuComponent.java
@@ -1,5 +1,5 @@
/* MenuComponent.java -- Superclass of all AWT menu components
- Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,15 +38,24 @@ exception statement from your version. */
package java.awt;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
import java.awt.peer.MenuComponentPeer;
import java.io.Serializable;
+import java.util.Locale;
-// FIXME: Java 1.0 event model unimplemented
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleComponent;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleSelection;
+import javax.accessibility.AccessibleStateSet;
/**
- * This is the superclass of all non-menu AWT widgets.
+ * This is the superclass of all menu AWT widgets.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Andrew John Hughes <gnu_andrew@member.fsf.org>
*/
public abstract class MenuComponent implements Serializable
{
@@ -59,31 +68,101 @@ public abstract class MenuComponent implements Serializable
private static final long serialVersionUID = -4536902356223894379L;
/*************************************************************************/
-
+
/*
* Instance Variables
*/
- // FIXME: missing serialized fields `nameExplicitlySet',
- // `newEventsOnly', and `accessibleContext'.
+/**
+ * The font for this component.
+ *
+ * @see #getFont()
+ * @see #setFont(java.awt.Font)
+ * @serial the component's font.
+ */
+ private Font font;
+
+ /**
+ * The name of the component.
+ *
+ * @see #getName()
+ * @see #setName(String)
+ * @serial the component's name.
+ */
+ private String name;
+
+ /**
+ * The parent of this component.
+ *
+ * @see #getParent()
+ * @see #setParent(java.awt.MenuContainer)
+ * @serial ignored.
+ */
+ transient MenuContainer parent;
-// The font for this component
-private Font font;
+ /**
+ * The native peer for this component.
+ *
+ * @see #getPeer()
+ * @see #setPeer(java.awt.peer.MenuComponentPeer)
+ * @serial ignored.
+ */
+ transient MenuComponentPeer peer;
-// The name of the component
-private String name;
+ /**
+ * The synchronization locking object for this component.
+ *
+ * @serial ignored.
+ */
+ private transient Object tree_lock = this;
-// The parent of this component
-transient MenuContainer parent;
+ /**
+ * The toolkit for this object.
+ *
+ * @see #getToolkit()
+ * @serial ignored.
+ */
+ private static transient Toolkit toolkit = Toolkit.getDefaultToolkit();
-// The native peer for this componet
-transient MenuComponentPeer peer;
+ /**
+ * The accessible context for this component.
+ *
+ * @see #getAccessibleContext()
+ * @serial the accessibility information for this component.
+ */
+ private AccessibleContext accessibleContext;
-// The synchronization locking object for this component
-private transient Object tree_lock = this;
+ /**
+ * Was the name of the component set? This value defaults
+ * to false and becomes true after a call to <code>setName()</code>.
+ * Please note that this does not guarantee that name will then
+ * be non-null, as this may be the value passed to <code>setName()</code>.
+ *
+ * @see #setName(String)
+ * @serial true if the name value has been explicitly set by calling
+ * <code>setName()</code>.
+ */
+ private boolean nameExplicitlySet;
-// The toolkit for this object
-private static transient Toolkit toolkit = Toolkit.getDefaultToolkit();
+ /**
+ * Does this component handle new events? Events will be handled
+ * by this component if this is true. Otherwise, they will be forwarded
+ * up the component hierarchy. This implementation does not use this
+ * variable; it is merely provided for serialization compatability.
+ *
+ * @see #dispatchEvent(AWTEvent)
+ * @serial true if events are to be processed locally. Unused.
+ */
+ private boolean newEventsOnly;
+
+ /**
+ * The focus listener chain handler which deals with focus events for
+ * the accessible context of this component.
+ *
+ * @see AccessibleAWTMenuComponent#addFocusListener(java.awt.event.FocusListener)
+ * @serial ignored.
+ */
+ private transient FocusListener focusListener;
/*************************************************************************/
@@ -117,7 +196,13 @@ MenuComponent()
public Font
getFont()
{
- return(font);
+ if (font != null)
+ return font;
+
+ if (parent != null)
+ return parent.getFont ();
+
+ return null;
}
/*************************************************************************/
@@ -157,6 +242,7 @@ public void
setName(String name)
{
this.name = name;
+ nameExplicitlySet = true;
}
/*************************************************************************/
@@ -260,13 +346,14 @@ setTreeLock(Object tree_lock)
* AWT 1.0 event dispatcher.
*
* @deprecated Deprecated in favor of <code>dispatchEvent()</code>.
+ * @return true if the event was dispatched, false otherwise.
*/
public boolean
postEvent(Event event)
{
- return(false);
+ // This is overridden by subclasses that support events.
+ return false;
}
-
/*************************************************************************/
/**
@@ -274,17 +361,35 @@ postEvent(Event event)
*
* @param event The event to dispatch
*/
-public final void
-dispatchEvent(AWTEvent event)
+public final void dispatchEvent(AWTEvent event)
{
// See comment in Component.dispatchEvent().
dispatchEventImpl(event);
}
-void
-dispatchEventImpl(AWTEvent e)
+
+/**
+ * Implementation of dispatchEvent. Allows trusted package classes
+ * to dispatch additional events first. This implementation first
+ * translates <code>event</code> to an AWT 1.0 event and sends the
+ * result to {@link #postEvent}. The event is then
+ * passed on to {@link #processEvent} for local processing.
+ *
+ * @param event the event to dispatch.
+ */
+void dispatchEventImpl(AWTEvent event)
{
+ Event oldStyleEvent;
+
// This is overridden by subclasses that support events.
+ /* Convert AWT 1.1 event to AWT 1.0 event */
+ oldStyleEvent = Component.translateEvent(event);
+ if (oldStyleEvent != null)
+ {
+ postEvent(oldStyleEvent);
+ }
+ /* Do local processing */
+ processEvent(event);
}
/*************************************************************************/
@@ -298,6 +403,25 @@ dispatchEventImpl(AWTEvent e)
protected void
processEvent(AWTEvent event)
{
+ /*
+ Pass a focus event to the focus listener for
+ the accessibility context.
+ */
+ if (event instanceof FocusEvent)
+ {
+ if (focusListener != null)
+ {
+ switch (event.id)
+ {
+ case FocusEvent.FOCUS_GAINED:
+ focusListener.focusGained((FocusEvent) event);
+ break;
+ case FocusEvent.FOCUS_LOST:
+ focusListener.focusLost((FocusEvent) event);
+ break;
+ }
+ }
+ }
}
/*************************************************************************/
@@ -316,15 +440,884 @@ toString()
/*************************************************************************/
/**
- * Returns a debugging string for this component
- */
+ * Returns a debugging string for this component
+ */
protected String
paramString()
{
return "name=" + getName();
}
-// Accessibility API not yet implemented.
-// public AccessibleContext getAccessibleContext()
+/**
+ * Gets the AccessibleContext associated with this <code>MenuComponent</code>.
+ * As an abstract class, we return null. Concrete subclasses should return
+ * their implementation of the accessibility context.
+ *
+ * @return null.
+ */
+
+public AccessibleContext getAccessibleContext()
+{
+ return null;
+}
+
+/**
+ * This class provides a base for the accessibility support of menu
+ * components.
+ *
+ * @author Andrew John Hughes <gnu_andrew@member.fsf.org>
+ */
+protected abstract class AccessibleAWTMenuComponent
+ extends AccessibleContext
+ implements Serializable, AccessibleComponent, AccessibleSelection
+{
+
+ /**
+ * Compatible with JDK 1.4.2 revision 5
+ */
+ private static final long serialVersionUID = -4269533416223798698L;
+
+ /**
+ * This is the default constructor. It should be called by
+ * concrete subclasses to ensure necessary groundwork is completed.
+ */
+ protected AccessibleAWTMenuComponent()
+ {
+ }
+
+ /**
+ * Replaces or supplements the component's selection with the
+ * <code>Accessible</code> child at the supplied index. If
+ * the component supports multiple selection, the child is
+ * added to the current selection. Otherwise, the current
+ * selection becomes the specified child. If the child is
+ * already selected, nothing happens.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param index the index of the specified child within a
+ * zero-based list of the component's children.
+ */
+ public void addAccessibleSelection(int index)
+ {
+ /* Subclasses with children should implement this */
+ }
+
+ /**
+ * Registers the specified focus listener to receive
+ * focus events from this component.
+ *
+ * @param listener the new focus listener.
+ */
+ public void addFocusListener(FocusListener listener)
+ {
+ /*
+ * Chain the new focus listener to the existing chain
+ * of focus listeners. Each new focus listener is
+ * coupled via multicasting to the existing chain.
+ */
+ focusListener = AWTEventMulticaster.add(focusListener, listener);
+ }
+
+ /**
+ * Clears the component's current selection. Following
+ * the calling of this method, no children of the component
+ * will be selected.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ */
+ public void clearAccessibleSelection()
+ {
+ }
+
+ /**
+ * Returns true if the specified point lies within the
+ * component. The supplied co-ordinates are assumed to
+ * be relative to the co-ordinate system of the component
+ * itself. Thus, the point (0,0) is the upper left corner
+ * of this component.
+ * <br />
+ * <br />
+ * Please note that this method depends on a correctly implemented
+ * version of the <code>getBounds()</code> method. Subclasses
+ * must provide the bounding rectangle via <code>getBounds()</code>
+ * in order for this method to work.
+ *
+ * @param point the point to check against this component.
+ * @return true if the point is within this component.
+ * @see #getBounds()
+ */
+ public boolean contains(Point point)
+ {
+ /*
+ We can simply return the result of a
+ test for containment in the bounding rectangle
+ */
+ return getBounds().contains(point);
+ }
+
+ /**
+ * Returns the <code>Accessible</code> child of this component present
+ * at the specified point. The supplied co-ordinates are
+ * assumed to be relative to the co-ordinate system of this
+ * component (the parent of any returned accessible). Thus,
+ * the point (0,0) is the upper left corner of this menu
+ * component.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param point the point at which the returned accessible
+ * is located.
+ * @return null.
+ */
+ public Accessible getAccessibleAt(Point point)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the <code>Accessible</code> child at the supplied
+ * index within the list of children of this component.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param index the index of the <code>Accessible</code> child
+ * to retrieve.
+ * @return null.
+ */
+ public Accessible getAccessibleChild(int index)
+ {
+ return null;
+ }
+
+ /**
+ * Returns the number of children of this component which
+ * implement the <code>Accessible</code> interface. If
+ * all children of this component are accessible, then
+ * the returned value will be the same as the number of
+ * children.
+ * <br />
+ * <br />
+ *
+ * @return 0.
+ */
+ public int getAccessibleChildrenCount()
+ {
+ return 0;
+ }
+
+ /**
+ * Retrieves the <code>AccessibleComponent</code> associated
+ * with this accessible context and its component. As the
+ * context itself implements <code>AccessibleComponent</code>,
+ * this is the return value.
+ *
+ * @return the context itself.
+ */
+ public AccessibleComponent getAccessibleComponent()
+ {
+ return this;
+ }
+
+ /**
+ * Returns the accessible name for this menu component. This
+ * is the name given to the component, which may be null if
+ * not set using <code>setName()</code>.
+ * <br />
+ * <br />
+ * The name is not the most appropriate description of this
+ * object. Subclasses should preferably provide a more
+ * accurate description. For example, a File menu could
+ * have the description `Lists commands related to the
+ * file system'.
+ *
+ * @return a description of the component. Currently,
+ * this is just the contents of the name property.
+ * @see MenuComponent#setName(String)
+ */
+ public String getAccessibleDescription()
+ {
+ return MenuComponent.this.getName();
+ }
+
+ /**
+ * Retrieves the index of this component within its parent.
+ * If no parent exists, -1 is returned.
+ *
+ * @return -1 as the parent, a <code>MenuContainer</code>
+ * is not <code>Accessible</code>.
+ */
+ public int getAccessibleIndexInParent()
+ {
+ return -1;
+ }
+
+ /**
+ * Returns the accessible name of this component. This
+ * is the name given to the component, which may be null if
+ * not set using <code>setName()</code>.
+ * <br />
+ * <br />
+ * The name property is not the most suitable string to return
+ * for this method. The string should be localized, and
+ * relevant to the operation of the component. For example,
+ * it could be the text of a menu item. However, this can
+ * not be used at this level of abstraction, so it is the
+ * responsibility of subclasses to provide a more appropriate
+ * name.
+ *
+ * @return a localized name for this component. Currently, this
+ * is just the contents of the name property.
+ * @see MenuComponent#setName(String)
+ */
+ public String getAccessibleName()
+ {
+ return MenuComponent.this.getName();
+ }
+
+ /**
+ * Returns the <code>Accessible</code> parent of this component.
+ * As the parent of a <code>MenuComponent</code> is a
+ * <code>MenuContainer</code>, which doesn't implement
+ * <code>Accessible</code>, this method returns null.
+ *
+ * @return null.
+ */
+ public Accessible getAccessibleParent()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the accessible role of this component.
+ * <br />
+ * <br />
+ * The abstract implementation of this method returns
+ * <code>AccessibleRole.AWT_COMPONENT</code>,
+ * as the abstract component has no specific role. This
+ * method should be overridden by concrete subclasses, so
+ * as to return an appropriate role for the component.
+ *
+ * @return <code>AccessibleRole.AWT_COMPONENT</code>.
+ */
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.AWT_COMPONENT;
+ }
+
+ /**
+ * Retrieves the <code>AccessibleSelection</code> associated
+ * with this accessible context and its component. As the
+ * context itself implements <code>AccessibleSelection</code>,
+ * this is the return value.
+ *
+ * @return the context itself.
+ */
+ public AccessibleSelection getAccessibleSelection()
+ {
+ return this;
+ }
+
+ /**
+ * Retrieves the <code>Accessible</code> selected child
+ * at the specified index. If there are no selected children
+ * or the index is outside the range of selected children,
+ * null is returned. Please note that the index refers
+ * to the index of the child in the list of <strong>selected
+ * children</strong>, and not the index of the child in
+ * the list of all <code>Accessible</code> children.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param index the index of the selected <code>Accessible</code>
+ * child.
+ */
+ public Accessible getAccessibleSelection(int index)
+ {
+ return null;
+ }
+
+ /**
+ * Returns a count of the number of <code>Accessible</code>
+ * children of this component which are currently selected.
+ * If there are no children currently selected, 0 is returned.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @return 0.
+ */
+ public int getAccessibleSelectionCount()
+ {
+ return 0;
+ }
+
+ /**
+ * Retrieves the current state of this component
+ * in an accessible form. For example, a given component
+ * may be visible, selected, disabled, etc.
+ * <br />
+ * <br />
+ * As this class tells us virtually nothing about the component,
+ * except for its name and font, no state information can be
+ * provided. This implementation thus returns an empty
+ * state set, and it is left to concrete subclasses to provide
+ * a more acceptable and relevant state set. Changes to these
+ * properties also need to be handled using
+ * <code>PropertyChangeListener</code>s.
+ *
+ * @return an empty <code>AccessibleStateSet</code>.
+ */
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ return new AccessibleStateSet();
+ }
+
+ /**
+ * Returns the background color of the component, or null
+ * if this property is unsupported.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply returns the
+ * default system background color used for rendering menus.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @return the default system background color for menus.
+ * @see #setBackground(java.awt.Color)
+ */
+ public Color getBackground()
+ {
+ return SystemColor.menu;
+ }
+
+ /**
+ * Returns a <code>Rectangle</code> which represents the
+ * bounds of this component. The returned rectangle has the
+ * height and width of the component's bounds, and is positioned
+ * at a location relative to this component's parent, the
+ * <code>MenuContainer</code>. null is returned if bounds
+ * are not supported by the component.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply returns null.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @return null.
+ * @see #setBounds(java.awt.Rectangle)
+ */
+ public Rectangle getBounds()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the <code>Cursor</code> displayed when the pointer
+ * is positioned over this component. Alternatively, null
+ * is returned if the component doesn't support the cursor
+ * property.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply returns the default
+ * system cursor. Concrete subclasses which handle the drawing
+ * of an onscreen menu component may override this method and provide
+ * the appropriate information.
+ *
+ * @return the default system cursor.
+ * @see #setCursor(java.awt.Cursor)
+ */
+ public Cursor getCursor()
+ {
+ return Cursor.getDefaultCursor();
+ }
+
+ /**
+ * Returns the <code>Font</code> used for text created by this component.
+ *
+ * @return the current font.
+ * @see #setFont(java.awt.Font)
+ */
+ public Font getFont()
+ {
+ return MenuComponent.this.getFont();
+ }
+
+ /**
+ * Retrieves information on the rendering and metrics of the supplied
+ * font. If font metrics are not supported by this component, null
+ * is returned.
+ * <br />
+ * <br />
+ * The abstract implementation of this method simply uses the toolkit
+ * to obtain the <code>FontMetrics</code>. Concrete subclasses may
+ * find it more efficient to invoke their peer class directly, if one
+ * is available.
+ *
+ * @param font the font about which to retrieve rendering and metric
+ * information.
+ * @return the metrics of the given font, as provided by the system
+ * toolkit.
+ * @throws NullPointerException if the supplied font was null.
+ */
+ public FontMetrics getFontMetrics(Font font)
+ {
+ return MenuComponent.this.getToolkit().getFontMetrics(font);
+ }
+
+ /**
+ * Returns the foreground color of the component, or null
+ * if this property is unsupported.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply returns the
+ * default system text color used for rendering menus.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @return the default system text color for menus.
+ * @see #setForeground(java.awt.Color)
+ */
+ public Color getForeground()
+ {
+ return SystemColor.menuText;
+ }
+
+ /**
+ * Returns the locale currently in use by this component.
+ * <br />
+ * <br />
+ * This abstract class has no property relating to the
+ * locale used by the component, so this method simply
+ * returns the default locale for the current instance
+ * of the Java Virtual Machine (JVM). Concrete subclasses
+ * which maintain such a property should override this method
+ * and provide the locale information more accurately.
+ *
+ * @return the default locale for this JVM instance.
+ */
+ public Locale getLocale()
+ {
+ return Locale.getDefault();
+ }
+
+ /**
+ * Returns the location of the component, with co-ordinates
+ * relative to the parent component and using the co-ordinate
+ * space of the screen. Thus, the point (0,0) is the upper
+ * left corner of the parent component.
+ * <br />
+ * <br />
+ * Please note that this method depends on a correctly implemented
+ * version of the <code>getBounds()</code> method. Subclasses
+ * must provide the bounding rectangle via <code>getBounds()</code>
+ * in order for this method to work.
+ *
+ * @return the location of the component, relative to its parent.
+ * @see #setLocation(java.awt.Point)
+ */
+ public Point getLocation()
+ {
+ /* Simply return the location of the bounding rectangle */
+ return getBounds().getLocation();
+ }
+
+ /**
+ * Returns the location of the component, with co-ordinates
+ * relative to the screen. Thus, the point (0,0) is the upper
+ * left corner of the screen. null is returned if the component
+ * is either not on screen or if this property is unsupported.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply returns null.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @return the location of the component, relative to the screen.
+ */
+ public Point getLocationOnScreen()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the size of the component.
+ * <br />
+ * <br />
+ * Please note that this method depends on a correctly implemented
+ * version of the <code>getBounds()</code> method. Subclasses
+ * must provide the bounding rectangle via <code>getBounds()</code>
+ * in order for this method to work.
+ *
+ * @return the size of the component.
+ * @see #setSize(java.awt.Dimension)
+ */
+ public Dimension getSize()
+ {
+ /* Simply return the size of the bounding rectangle */
+ return getBounds().getSize();
+ }
+
+ /**
+ * Returns true if the accessible child specified by the supplied index
+ * is currently selected.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param index the index of the accessible child to check for selection.
+ * @return false.
+ */
+ public boolean isAccessibleChildSelected(int index)
+ {
+ return false;
+ }
+
+ /**
+ * Returns true if this component is currently enabled.
+ * <br />
+ * <br />
+ * As this abstract component has no properties related to
+ * its enabled or disabled state, the implementation of this
+ * method is left to subclasses.
+ *
+ * @return false.
+ * @see #setEnabled(boolean)
+ */
+ public boolean isEnabled()
+ {
+ return false;
+ }
+
+ /**
+ * Returns true if this component is included in the traversal
+ * of the current focus from one component to the other.
+ * <br />
+ * <br />
+ * As this abstract component has no properties related to
+ * its ability to accept the focus, the implementation of this
+ * method is left to subclasses.
+ *
+ * @return false.
+ */
+ public boolean isFocusTraversable()
+ {
+ return false;
+ }
+
+ /**
+ * Returns true if the component is being shown on screen.
+ * A component is determined to be shown if it is visible,
+ * and each parent component is also visible. Please note
+ * that, even when a component is showing, it may still be
+ * obscured by other components in front. This method only
+ * determines if the component is being drawn on the screen.
+ * <br />
+ * <br />
+ * As this abstract component and its parent have no properties
+ * relating to visibility, the implementation of this method is
+ * left to subclasses.
+ *
+ * @return false.
+ * @see #isVisible()
+ */
+ public boolean isShowing()
+ {
+ return false;
+ }
+
+ /**
+ * Returns true if the component is visible. A component may
+ * be visible but not drawn on the screen if one of its parent
+ * components is not visible. To determine if the component is
+ * actually drawn on screen, <code>isShowing()</code> should be
+ * used.
+ * <br />
+ * <br />
+ * As this abstract component has no properties relating to its
+ * visibility, the implementation of this method is left to subclasses.
+ *
+ * @return false.
+ * @see #isShowing()
+ * @see #setVisible(boolean)
+ */
+ public boolean isVisible()
+ {
+ return false;
+ }
+
+ /**
+ * Removes the accessible child specified by the supplied index from
+ * the list of currently selected children. If the child specified
+ * is not selected, nothing happens.
+ * <br />
+ * <br />
+ * As the existence of children can not be determined from
+ * this abstract class, the implementation of this method
+ * is left to subclasses.
+ *
+ * @param index the index of the <code>Accessible</code> child.
+ */
+ public void removeAccessibleSelection(int index)
+ {
+ /* Subclasses with children should implement this */
+ }
+
+ /**
+ * Removes the specified focus listener from the list of registered
+ * focus listeners for this component.
+ *
+ * @param listener the listener to remove.
+ */
+ public void removeFocusListener(FocusListener listener)
+ {
+ /* Remove the focus listener from the chain */
+ focusListener = AWTEventMulticaster.remove(focusListener, listener);
+ }
+
+ /**
+ * Requests that this component gains focus. This depends on the
+ * component being focus traversable.
+ * <br />
+ * <br />
+ * As this abstract component has no properties relating to its
+ * focus traversability, or access to a peer with request focusing
+ * abilities, the implementation of this method is left to subclasses.
+ */
+ public void requestFocus()
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Selects all <code>Accessible</code> children of this component which
+ * it is possible to select. The component needs to support multiple
+ * selections.
+ * <br />
+ * <br />
+ * This abstract component provides a simplistic implementation of this
+ * method, which ignores the ability of the component to support multiple
+ * selections and simply uses <code>addAccessibleSelection</code> to
+ * add each <code>Accessible</code> child to the selection. The last
+ * <code>Accessible</code> component is thus selected for components
+ * which don't support multiple selections. Concrete implementations should
+ * override this with a more appopriate and efficient implementation, which
+ * properly takes into account the ability of the component to support multiple
+ * selections.
+ */
+ public void selectAllAccessibleSelection()
+ {
+ /* Simply call addAccessibleSelection() on all accessible children */
+ for (int a = 0; a < getAccessibleChildrenCount(); ++a)
+ {
+ addAccessibleSelection(a);
+ }
+ }
+
+ /**
+ * Sets the background color of the component to that specified.
+ * Unspecified behaviour occurs when null is given as the new
+ * background color.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply ignores the supplied
+ * color and continues to use the default system color.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @param color the new color to use for the background.
+ * @see getBackground()
+ */
+ public void setBackground(Color color)
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Sets the height and width of the component, and its position
+ * relative to this component's parent, to the values specified
+ * by the supplied rectangle. Unspecified behaviour occurs when
+ * null is given as the new bounds.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply ignores the new
+ * rectangle and continues to return null from <code>getBounds()</code>.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @param rectangle a rectangle which specifies the new bounds of
+ * the component.
+ * @see #getBounds()
+ */
+ public void setBounds(Rectangle rectangle)
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Sets the <code>Cursor</code> used when the pointer is positioned over the
+ * component. Unspecified behaviour occurs when null is given as the new
+ * cursor.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply ignores the new cursor
+ * and continues to return the default system cursor. Concrete
+ * subclasses which handle the drawing of an onscreen menu component
+ * may override this method and provide the appropriate information.
+ *
+ * @param cursor the new cursor to use.
+ * @see #getCursor()
+ */
+ public void setCursor(Cursor cursor)
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Sets the enabled/disabled state of this component.
+ * <br />
+ * <br />
+ * As this abstract component has no properties related to
+ * its enabled or disabled state, the implementation of this
+ * method is left to subclasses.
+ *
+ * @param enabled true if the component should be enabled,
+ * false otherwise.
+ * @see #getEnabled()
+ */
+ public void setEnabled(boolean enabled)
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Sets the <code>Font</code> used for text created by this component.
+ * Unspecified behaviour occurs when null is given as the new
+ * font.
+ *
+ * @param font the new font to use for text.
+ * @see #getFont()
+ */
+ public void setFont(Font font)
+ {
+ /* Call the method of the enclosing component */
+ MenuComponent.this.setFont(font);
+ }
+
+ /**
+ * Sets the foreground color of the component to that specified.
+ * Unspecified behaviour occurs when null is given as the new
+ * background color.
+ * <br />
+ * <br />
+ * This abstract class knows nothing about how the component
+ * is drawn on screen, so this method simply ignores the supplied
+ * color and continues to return the default system text color used
+ * for rendering menus.
+ * Concrete subclasses which handle the drawing of an onscreen
+ * menu component should override this method and provide
+ * the appropriate information.
+ *
+ * @param color the new foreground color.
+ * @see #getForeground()
+ */
+ public void setForeground(Color color)
+ {
+ /* Ignored */
+ }
+
+ /**
+ * Sets the location of the component, with co-ordinates
+ * relative to the parent component and using the co-ordinate
+ * space of the screen. Thus, the point (0,0) is the upper
+ * left corner of the parent component.
+ * <br />
+ * <br />
+ * Please note that this method depends on a correctly implemented
+ * version of the <code>getBounds()</code> method. Subclasses
+ * must provide the bounding rectangle via <code>getBounds()</code>
+ * in order for this method to work.
+ *
+ * @param point the location of the component, relative to its parent.
+ * @see #getLocation()
+ */
+ public void setLocation(Point point)
+ {
+ getBounds().setLocation(point);
+ }
+
+ /**
+ * Sets the size of the component.
+ * <br />
+ * <br />
+ * Please note that this method depends on a correctly implemented
+ * version of the <code>getBounds()</code> method. Subclasses
+ * must provide the bounding rectangle via <code>getBounds()</code>
+ * in order for this method to work.
+ *
+ * @param size the new size of the component.
+ * @see #getSize()
+ */
+ public void setSize(Dimension size)
+ {
+ getBounds().setSize(size);
+ }
+
+ /**
+ * Sets the visibility state of the component. A component may
+ * be visible but not drawn on the screen if one of its parent
+ * components is not visible. To determine if the component is
+ * actually drawn on screen, <code>isShowing()</code> should be
+ * used.
+ * <br />
+ * <br />
+ * As this abstract component has no properties relating to its
+ * visibility, the implementation of this method is left to subclasses.
+ *
+ * @param visibility the new visibility of the component -- true if
+ * the component is visible, false if not.
+ * @see #isShowing()
+ * @see #isVisible()
+ */
+ public void setVisible(boolean visibility)
+ {
+ /* Ignored */
+ }
+
+} /* class AccessibleAWTMenuComponent */
+
-} // class Component
+} // class MenuComponent
diff --git a/libjava/java/awt/MenuItem.java b/libjava/java/awt/MenuItem.java
index 81a4a79bcfa..a58774240ff 100644
--- a/libjava/java/awt/MenuItem.java
+++ b/libjava/java/awt/MenuItem.java
@@ -45,17 +45,20 @@ import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.EventListener;
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleAction;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleValue;
+
/**
* This class represents an item in a menu.
*
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class MenuItem extends MenuComponent
- implements Serializable
+ implements Serializable, Accessible
{
-// FIXME: The enabled event mask is not used at this time.
-
/*
* Static Variables
*/
@@ -97,6 +100,110 @@ private MenuShortcut shortcut;
// The list of action listeners for this menu item.
private transient ActionListener action_listeners;
+ protected class AccessibleAWTMenuItem
+ extends MenuComponent.AccessibleAWTMenuComponent
+ implements AccessibleAction, AccessibleValue
+ {
+ /** Constructor */
+ public AccessibleAWTMenuItem()
+ {
+ super();
+ }
+
+
+
+ public String getAccessibleName()
+ {
+ return label;
+ }
+
+ public AccessibleAction getAccessibleAction()
+ {
+ return this;
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.MENU_ITEM;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionCount()
+ */
+ public int getAccessibleActionCount()
+ {
+ return 1;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#getAccessibleActionDescription(int)
+ */
+ public String getAccessibleActionDescription(int i)
+ {
+ if (i == 0)
+ return label;
+ else
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleAction#doAccessibleAction(int)
+ */
+ public boolean doAccessibleAction(int i)
+ {
+ if (i != 0)
+ return false;
+ processActionEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand));
+ return true;
+ }
+
+ public AccessibleValue getAccessibleValue()
+ {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getCurrentAccessibleValue()
+ */
+ public Number getCurrentAccessibleValue()
+ {
+ return (enabled) ? new Integer(1) : new Integer(0);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#setCurrentAccessibleValue(java.lang.Number)
+ */
+ public boolean setCurrentAccessibleValue(Number number)
+ {
+ if (number.intValue() == 0)
+ {
+ setEnabled(false);
+ return false;
+ }
+
+ setEnabled(true);
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getMinimumAccessibleValue()
+ */
+ public Number getMinimumAccessibleValue()
+ {
+ return new Integer(0);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleValue#getMaximumAccessibleValue()
+ */
+ public Number getMaximumAccessibleValue()
+ {
+ return new Integer(0);
+ }
+
+ }
+
+
/*************************************************************************/
/*
diff --git a/libjava/java/awt/Panel.java b/libjava/java/awt/Panel.java
index dbe322896d7..1ba9fbd246e 100644
--- a/libjava/java/awt/Panel.java
+++ b/libjava/java/awt/Panel.java
@@ -1,5 +1,5 @@
/* Panel.java -- Simple container object
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,7 +38,6 @@ exception statement from your version. */
package java.awt;
-import java.awt.event.PaintEvent;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
@@ -47,8 +46,8 @@ import javax.accessibility.AccessibleRole;
* A panel is a simple container class. It's default layout is the
* <code>FlowLayout</code> manager.
*
- * @author Aaron M. Renn <arenn@urbanophile.com>
- * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
* @see FlowLayout
* @since 1.0
* @status updated to 1.4
@@ -74,7 +73,7 @@ public class Panel extends Container implements Accessible
/*
* The number used to generate the name returned by getName.
*/
- private static transient long next_panel_number = 0;
+ private static transient long next_panel_number;
/**
* Initializes a new instance of <code>Panel</code> that has a default
@@ -98,36 +97,6 @@ public class Panel extends Container implements Accessible
}
/**
- * Consume initial application-requested paint event if it has not
- * already been consumed, and if the initial system-requested paint
- * event has not already been handled. Otherwise, call
- * super.dispatchEventImpl. These extra steps are required to
- * prevent a Panel from being painted twice when it is initially
- * shown.
- *
- * @param e the event to dispatch
- */
- void dispatchEventImpl (AWTEvent e)
- {
- if (e instanceof PaintEvent)
- {
- if (e.id == PaintEvent.UPDATE)
- {
- if (!initialUpdateConsumed
- && !initialSystemUpdateDone)
- {
- e.consume ();
- initialUpdateConsumed = true;
- }
- }
- else if (e.id == PaintEvent.PAINT)
- initialSystemUpdateDone = true;
- }
- else
- super.dispatchEventImpl (e);
- }
-
- /**
* Notifies this object to create its native peer.
*
* @see #isDisplayable()
diff --git a/libjava/java/awt/Point.java b/libjava/java/awt/Point.java
index 9d5126434ae..3731b4134ee 100644
--- a/libjava/java/awt/Point.java
+++ b/libjava/java/awt/Point.java
@@ -95,7 +95,7 @@ public class Point extends Point2D implements Serializable
* Initializes a new instance of <code>Point</code> with coordinates
* identical to the coordinates of the specified points.
*
- * @param point the point to copy the coordinates from
+ * @param p the point to copy the coordinates from
* @throws NullPointerException if p is null
*/
public Point(Point p)
diff --git a/libjava/java/awt/Polygon.java b/libjava/java/awt/Polygon.java
index 96c370aafc1..4b89bd669f2 100644
--- a/libjava/java/awt/Polygon.java
+++ b/libjava/java/awt/Polygon.java
@@ -1,5 +1,5 @@
/* Polygon.java -- class representing a polygon
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,6 +39,7 @@ exception statement from your version. */
package java.awt;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Line2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
@@ -100,17 +101,8 @@ public class Polygon implements Shape, Serializable
*/
protected Rectangle bounds;
- /**
- * Cached flattened version - condense points and parallel lines, so the
- * result has area if there are >= 3 condensed vertices. flat[0] is the
- * number of condensed points, and (flat[odd], flat[odd+1]) form the
- * condensed points.
- *
- * @see #condense()
- * @see #contains(double, double)
- * @see #contains(double, double, double, double)
- */
- private transient int[] condensed;
+ /** A big number, but not so big it can't survive a few float operations */
+ private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
/**
* Initializes an empty polygon.
@@ -168,7 +160,6 @@ public class Polygon implements Shape, Serializable
public void invalidate()
{
bounds = null;
- condensed = null;
}
/**
@@ -184,15 +175,14 @@ public class Polygon implements Shape, Serializable
int i = npoints;
while (--i >= 0)
{
- xpoints[i] += dx;
- ypoints[i] += dy;
+ xpoints[i] += dx;
+ ypoints[i] += dy;
}
if (bounds != null)
{
- bounds.x += dx;
- bounds.y += dy;
+ bounds.x += dx;
+ bounds.y += dy;
}
- condensed = null;
}
/**
@@ -206,45 +196,44 @@ public class Polygon implements Shape, Serializable
{
if (npoints + 1 > xpoints.length)
{
- int[] newx = new int[npoints + 1];
- System.arraycopy(xpoints, 0, newx, 0, npoints);
- xpoints = newx;
+ int[] newx = new int[npoints + 1];
+ System.arraycopy(xpoints, 0, newx, 0, npoints);
+ xpoints = newx;
}
if (npoints + 1 > ypoints.length)
{
- int[] newy = new int[npoints + 1];
- System.arraycopy(ypoints, 0, newy, 0, npoints);
- ypoints = newy;
+ int[] newy = new int[npoints + 1];
+ System.arraycopy(ypoints, 0, newy, 0, npoints);
+ ypoints = newy;
}
xpoints[npoints] = x;
ypoints[npoints] = y;
npoints++;
if (bounds != null)
{
- if (npoints == 1)
- {
- bounds.x = x;
- bounds.y = y;
- }
- else
- {
- if (x < bounds.x)
- {
- bounds.width += bounds.x - x;
- bounds.x = x;
- }
- else if (x > bounds.x + bounds.width)
- bounds.width = x - bounds.x;
- if (y < bounds.y)
- {
- bounds.height += bounds.y - y;
- bounds.y = y;
- }
- else if (y > bounds.y + bounds.height)
- bounds.height = y - bounds.y;
- }
+ if (npoints == 1)
+ {
+ bounds.x = x;
+ bounds.y = y;
+ }
+ else
+ {
+ if (x < bounds.x)
+ {
+ bounds.width += bounds.x - x;
+ bounds.x = x;
+ }
+ else if (x > bounds.x + bounds.width)
+ bounds.width = x - bounds.x;
+ if (y < bounds.y)
+ {
+ bounds.height += bounds.y - y;
+ bounds.y = y;
+ }
+ else if (y > bounds.y + bounds.height)
+ bounds.height = y - bounds.y;
+ }
}
- condensed = null;
}
/**
@@ -258,7 +247,7 @@ public class Polygon implements Shape, Serializable
*/
public Rectangle getBounds()
{
- return getBoundingBox ();
+ return getBoundingBox();
}
/**
@@ -274,27 +263,27 @@ public class Polygon implements Shape, Serializable
{
if (bounds == null)
{
- if (npoints == 0)
- return bounds = new Rectangle ();
- int i = npoints - 1;
- int minx = xpoints[i];
- int maxx = minx;
- int miny = ypoints[i];
- int maxy = miny;
- while (--i >= 0)
- {
- int x = xpoints[i];
- int y = ypoints[i];
- if (x < minx)
- minx = x;
- else if (x > maxx)
- maxx = x;
- if (y < miny)
- miny = y;
- else if (y > maxy)
- maxy = y;
- }
- bounds = new Rectangle (minx, miny, maxx - minx, maxy - miny);
+ if (npoints == 0)
+ return bounds = new Rectangle();
+ int i = npoints - 1;
+ int minx = xpoints[i];
+ int maxx = minx;
+ int miny = ypoints[i];
+ int maxy = miny;
+ while (--i >= 0)
+ {
+ int x = xpoints[i];
+ int y = ypoints[i];
+ if (x < minx)
+ minx = x;
+ else if (x > maxx)
+ maxx = x;
+ if (y < miny)
+ miny = y;
+ else if (y > maxy)
+ maxy = y;
+ }
+ bounds = new Rectangle(minx, miny, maxx - minx, maxy - miny);
}
return bounds;
}
@@ -365,64 +354,7 @@ public class Polygon implements Shape, Serializable
*/
public boolean contains(double x, double y)
{
- // First, the obvious bounds checks.
- if (! condense() || ! getBounds().contains(x, y))
- return false;
- // A point is contained if a ray to (-inf, y) crosses an odd number
- // of segments. This must obey the semantics of Shape when the point is
- // exactly on a segment or vertex: a point is inside only if the adjacent
- // point in the increasing x or y direction is also inside. Note that we
- // are guaranteed that the condensed polygon has area, and no consecutive
- // segments with identical slope.
- boolean inside = false;
- int limit = condensed[0];
- int curx = condensed[(limit << 1) - 1];
- int cury = condensed[limit << 1];
- for (int i = 1; i <= limit; i++)
- {
- int priorx = curx;
- int priory = cury;
- curx = condensed[(i << 1) - 1];
- cury = condensed[i << 1];
- if ((priorx > x && curx > x) // Left of segment, or NaN.
- || (priory > y && cury > y) // Below segment, or NaN.
- || (priory < y && cury < y)) // Above segment.
- continue;
- if (priory == cury) // Horizontal segment, y == cury == priory
- {
- if (priorx < x && curx < x) // Right of segment.
- {
- inside = ! inside;
- continue;
- }
- // Did we approach this segment from above or below?
- // This mess is necessary to obey rules of Shape.
- priory = condensed[((limit + i - 2) % limit) << 1];
- boolean above = priory > cury;
- if ((curx == x && (curx > priorx || above))
- || (priorx == x && (curx < priorx || ! above))
- || (curx > priorx && ! above) || above)
- inside = ! inside;
- continue;
- }
- if (priorx == x && priory == y) // On prior vertex.
- continue;
- if (priorx == curx // Vertical segment.
- || (priorx < x && curx < x)) // Right of segment.
- {
- inside = ! inside;
- continue;
- }
- // The point is inside the segment's bounding box, compare slopes.
- double leftx = curx > priorx ? priorx : curx;
- double lefty = curx > priorx ? priory : cury;
- double slopeseg = (double) (cury - priory) / (curx - priorx);
- double slopepoint = (double) (y - lefty) / (x - leftx);
- if ((slopeseg > 0 && slopeseg > slopepoint)
- || slopeseg < slopepoint)
- inside = ! inside;
- }
- return inside;
+ return ((evaluateCrossings(x, y, false, BIG_VALUE) & 1) != 0);
}
/**
@@ -453,67 +385,17 @@ public class Polygon implements Shape, Serializable
*/
public boolean intersects(double x, double y, double w, double h)
{
- // First, the obvious bounds checks.
- if (w <= 0 || h <= 0 || npoints == 0 ||
- ! getBounds().intersects(x, y, w, h))
- return false; // Disjoint bounds.
- if ((x <= bounds.x && x + w >= bounds.x + bounds.width
- && y <= bounds.y && y + h >= bounds.y + bounds.height)
- || contains(x, y))
- return true; // Rectangle contains the polygon, or one point matches.
- // If any vertex is in the rectangle, the two might intersect.
- int curx = 0;
- int cury = 0;
- for (int i = 0; i < npoints; i++)
- {
- curx = xpoints[i];
- cury = ypoints[i];
- if (curx >= x && curx < x + w && cury >= y && cury < y + h
- && contains(curx, cury)) // Boundary check necessary.
- return true;
- }
- // Finally, if at least one of the four bounding lines intersect any
- // segment of the polygon, return true. Be careful of the semantics of
- // Shape; coinciding lines do not necessarily return true.
- for (int i = 0; i < npoints; i++)
- {
- int priorx = curx;
- int priory = cury;
- curx = xpoints[i];
- cury = ypoints[i];
- if (priorx == curx) // Vertical segment.
- {
- if (curx < x || curx >= x + w) // Outside rectangle.
- continue;
- if ((cury >= y + h && priory <= y)
- || (cury <= y && priory >= y + h))
- return true; // Bisects rectangle.
- continue;
- }
- if (priory == cury) // Horizontal segment.
- {
- if (cury < y || cury >= y + h) // Outside rectangle.
- continue;
- if ((curx >= x + w && priorx <= x)
- || (curx <= x && priorx >= x + w))
- return true; // Bisects rectangle.
- continue;
- }
- // Slanted segment.
- double slope = (double) (cury - priory) / (curx - priorx);
- double intersect = slope * (x - curx) + cury;
- if (intersect > y && intersect < y + h) // Intersects left edge.
- return true;
- intersect = slope * (x + w - curx) + cury;
- if (intersect > y && intersect < y + h) // Intersects right edge.
- return true;
- intersect = (y - cury) / slope + curx;
- if (intersect > x && intersect < x + w) // Intersects bottom edge.
- return true;
- intersect = (y + h - cury) / slope + cury;
- if (intersect > x && intersect < x + w) // Intersects top edge.
- return true;
- }
+ /* Does any edge intersect? */
+ if (evaluateCrossings(x, y, false, w) != 0 /* top */
+ || evaluateCrossings(x, y + h, false, w) != 0 /* bottom */
+ || evaluateCrossings(x + w, y, true, h) != 0 /* right */
+ || evaluateCrossings(x, y, true, h) != 0) /* left */
+ return true;
+
+ /* No intersections, is any point inside? */
+ if ((evaluateCrossings(x, y, false, BIG_VALUE) & 1) != 0)
+ return true;
+
return false;
}
@@ -547,59 +429,21 @@ public class Polygon implements Shape, Serializable
*/
public boolean contains(double x, double y, double w, double h)
{
- // First, the obvious bounds checks.
- if (w <= 0 || h <= 0 || ! contains(x, y)
- || ! bounds.contains(x, y, w, h))
+ if (! getBounds2D().intersects(x, y, w, h))
return false;
- // Now, if any of the four bounding lines intersects a polygon segment,
- // return false. The previous check had the side effect of setting
- // the condensed array, which we use. Be careful of the semantics of
- // Shape; coinciding lines do not necessarily return false.
- int limit = condensed[0];
- int curx = condensed[(limit << 1) - 1];
- int cury = condensed[limit << 1];
- for (int i = 1; i <= limit; i++)
- {
- int priorx = curx;
- int priory = cury;
- curx = condensed[(i << 1) - 1];
- cury = condensed[i << 1];
- if (curx > x && curx < x + w && cury > y && cury < y + h)
- return false; // Vertex is in rectangle.
- if (priorx == curx) // Vertical segment.
- {
- if (curx < x || curx > x + w) // Outside rectangle.
- continue;
- if ((cury >= y + h && priory <= y)
- || (cury <= y && priory >= y + h))
- return false; // Bisects rectangle.
- continue;
- }
- if (priory == cury) // Horizontal segment.
- {
- if (cury < y || cury > y + h) // Outside rectangle.
- continue;
- if ((curx >= x + w && priorx <= x)
- || (curx <= x && priorx >= x + w))
- return false; // Bisects rectangle.
- continue;
- }
- // Slanted segment.
- double slope = (double) (cury - priory) / (curx - priorx);
- double intersect = slope * (x - curx) + cury;
- if (intersect > y && intersect < y + h) // Intersects left edge.
- return false;
- intersect = slope * (x + w - curx) + cury;
- if (intersect > y && intersect < y + h) // Intersects right edge.
- return false;
- intersect = (y - cury) / slope + curx;
- if (intersect > x && intersect < x + w) // Intersects bottom edge.
- return false;
- intersect = (y + h - cury) / slope + cury;
- if (intersect > x && intersect < x + w) // Intersects top edge.
- return false;
- }
- return true;
+
+ /* Does any edge intersect? */
+ if (evaluateCrossings(x, y, false, w) != 0 /* top */
+ || evaluateCrossings(x, y + h, false, w) != 0 /* bottom */
+ || evaluateCrossings(x + w, y, true, h) != 0 /* right */
+ || evaluateCrossings(x, y, true, h) != 0) /* left */
+ return false;
+
+ /* No intersections, is any point inside? */
+ if ((evaluateCrossings(x, y, false, BIG_VALUE) & 1) != 0)
+ return true;
+
+ return false;
}
/**
@@ -631,47 +475,47 @@ public class Polygon implements Shape, Serializable
public PathIterator getPathIterator(final AffineTransform transform)
{
return new PathIterator()
- {
- /** The current vertex of iteration. */
- private int vertex;
-
- public int getWindingRule()
{
- return WIND_EVEN_ODD;
- }
-
- public boolean isDone()
- {
- return vertex > npoints;
- }
-
- public void next()
- {
- vertex++;
- }
-
- public int currentSegment(float[] coords)
- {
- if (vertex >= npoints)
- return SEG_CLOSE;
- coords[0] = xpoints[vertex];
- coords[1] = ypoints[vertex];
- if (transform != null)
- transform.transform(coords, 0, coords, 0, 1);
- return vertex == 0 ? SEG_MOVETO : SEG_LINETO;
- }
-
- public int currentSegment(double[] coords)
- {
- if (vertex >= npoints)
- return SEG_CLOSE;
- coords[0] = xpoints[vertex];
- coords[1] = ypoints[vertex];
- if (transform != null)
- transform.transform(coords, 0, coords, 0, 1);
- return vertex == 0 ? SEG_MOVETO : SEG_LINETO;
- }
- };
+ /** The current vertex of iteration. */
+ private int vertex;
+
+ public int getWindingRule()
+ {
+ return WIND_EVEN_ODD;
+ }
+
+ public boolean isDone()
+ {
+ return vertex > npoints;
+ }
+
+ public void next()
+ {
+ vertex++;
+ }
+
+ public int currentSegment(float[] coords)
+ {
+ if (vertex >= npoints)
+ return SEG_CLOSE;
+ coords[0] = xpoints[vertex];
+ coords[1] = ypoints[vertex];
+ if (transform != null)
+ transform.transform(coords, 0, coords, 0, 1);
+ return vertex == 0 ? SEG_MOVETO : SEG_LINETO;
+ }
+
+ public int currentSegment(double[] coords)
+ {
+ if (vertex >= npoints)
+ return SEG_CLOSE;
+ coords[0] = xpoints[vertex];
+ coords[1] = ypoints[vertex];
+ if (transform != null)
+ transform.transform(coords, 0, coords, 0, 1);
+ return vertex == 0 ? SEG_MOVETO : SEG_LINETO;
+ }
+ };
}
/**
@@ -684,7 +528,7 @@ public class Polygon implements Shape, Serializable
* path iterator is not either.
*
* @param transform an optional transform to apply to the iterator
- * @param double the maximum distance for deviation from the real boundary
+ * @param flatness the maximum distance for deviation from the real boundary
* @return a new iterator over the boundary
* @since 1.2
*/
@@ -695,57 +539,75 @@ public class Polygon implements Shape, Serializable
}
/**
- * Helper for contains, which caches a condensed version of the polygon.
- * This condenses all colinear points, so that consecutive segments in
- * the condensed version always have different slope.
+ * Helper for contains, intersects, calculates the number of intersections
+ * between the polygon and a line extending from the point (x, y) along
+ * the positive X, or Y axis, within a given interval.
*
- * @return true if the condensed polygon has area
+ * @return the winding number.
* @see #condensed
* @see #contains(double, double)
*/
- private boolean condense()
+ private int evaluateCrossings(double x, double y, boolean useYaxis,
+ double distance)
{
- if (npoints <= 2)
- return false;
- if (condensed != null)
- return condensed[0] > 2;
- condensed = new int[npoints * 2 + 1];
- int curx = xpoints[npoints - 1];
- int cury = ypoints[npoints - 1];
- double curslope = Double.NaN;
- int count = 0;
- outer:
- for (int i = 0; i < npoints; i++)
+ double x0;
+ double x1;
+ double y0;
+ double y1;
+ double epsilon = 0.0;
+ int crossings = 0;
+ int[] xp;
+ int[] yp;
+
+ if (useYaxis)
{
- int priorx = curx;
- int priory = cury;
- double priorslope = curslope;
- curx = xpoints[i];
- cury = ypoints[i];
- while (curx == priorx && cury == priory)
- {
- if (++i == npoints)
- break outer;
- curx = xpoints[i];
- cury = ypoints[i];
- }
- curslope = (curx == priorx ? Double.POSITIVE_INFINITY
- : (double) (cury - priory) / (curx - priorx));
- if (priorslope == curslope)
- {
- if (count > 1 && condensed[(count << 1) - 3] == curx
- && condensed[(count << 1) - 2] == cury)
- {
- count--;
- continue;
- }
- }
- else
- count++;
- condensed[(count << 1) - 1] = curx;
- condensed[count << 1] = cury;
+ xp = ypoints;
+ yp = xpoints;
+ double swap;
+ swap = y;
+ y = x;
+ x = swap;
}
- condensed[0] = count;
- return count > 2;
+ else
+ {
+ xp = xpoints;
+ yp = ypoints;
+ }
+
+ /* Get a value which is small but not insignificant relative the path. */
+ epsilon = 1E-7;
+
+ x0 = xp[0] - x;
+ y0 = yp[0] - y;
+ for (int i = 1; i < npoints; i++)
+ {
+ x1 = xp[i] - x;
+ y1 = yp[i] - y;
+
+ if (y0 == 0.0)
+ y0 -= epsilon;
+ if (y1 == 0.0)
+ y1 -= epsilon;
+ if (y0 * y1 < 0)
+ if (Line2D.linesIntersect(x0, y0, x1, y1, epsilon, 0.0, distance, 0.0))
+ ++crossings;
+
+ x0 = xp[i] - x;
+ y0 = yp[i] - y;
+ }
+
+ // end segment
+ x1 = xp[0] - x;
+ y1 = yp[0] - y;
+ if (y0 == 0.0)
+ y0 -= epsilon;
+ if (y1 == 0.0)
+ y1 -= epsilon;
+ if (y0 * y1 < 0)
+ if (Line2D.linesIntersect(x0, y0, x1, y1, epsilon, 0.0, distance, 0.0))
+ ++crossings;
+
+ return crossings;
}
} // class Polygon
+
diff --git a/libjava/java/awt/PopupMenu.java b/libjava/java/awt/PopupMenu.java
index 83ffb35a85e..75082029186 100644
--- a/libjava/java/awt/PopupMenu.java
+++ b/libjava/java/awt/PopupMenu.java
@@ -1,5 +1,5 @@
/* PopupMenu.java -- An AWT popup menu
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,9 +38,11 @@ exception statement from your version. */
package java.awt;
-import java.awt.peer.MenuPeer;
import java.awt.peer.PopupMenuPeer;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+
/**
* This class implement an AWT popup menu widget
*
@@ -136,5 +138,23 @@ show(Component component, int x, int y)
}
}
+ protected class AccessibleAWTPopupMenu extends AccessibleAWTMenu
+ {
+ protected AccessibleAWTPopupMenu()
+ {
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.POPUP_MENU;
+ }
+
+ }
+
+ public AccessibleContext getAccessibleContext()
+ {
+ return new AccessibleAWTPopupMenu();
+ }
+
} // class PopupMenu
diff --git a/libjava/java/awt/Rectangle.java b/libjava/java/awt/Rectangle.java
index 5dc54116fd2..66190960a12 100644
--- a/libjava/java/awt/Rectangle.java
+++ b/libjava/java/awt/Rectangle.java
@@ -338,7 +338,7 @@ public class Rectangle extends Rectangle2D implements Shape, Serializable
* its upper left corner.
*
* @return the point where this rectangle is located
- * @see setLocation(Point)
+ * @see #setLocation(Point)
* @since 1.1
*/
public Point getLocation()
diff --git a/libjava/java/awt/RenderingHints.java b/libjava/java/awt/RenderingHints.java
index 9dc6d5f6419..a1ccdff3097 100644
--- a/libjava/java/awt/RenderingHints.java
+++ b/libjava/java/awt/RenderingHints.java
@@ -1,5 +1,5 @@
/* RenderingHints.java --
- Copyright (C) 2000, 2001, 2002 Free Software Foundation
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -41,38 +41,75 @@ package java.awt;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
- * NEEDS DOCUMENTATION
+ * A collection of (key, value) items that provide 'hints' for the
+ * {@link java.awt.Graphics2D} rendering pipeline. Because these
+ * items are hints only, they may be ignored by a particular
+ * {@link java.awt.Graphics2D} implementation.
*
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
* @author Eric Blake <ebb9@email.byu.edu>
*/
public class RenderingHints implements Map, Cloneable
{
+ /**
+ * The base class used to represent keys.
+ */
public abstract static class Key
{
private final int key;
+ /**
+ * Creates a new key.
+ *
+ * @param privateKey the private key.
+ */
protected Key(int privateKey)
{
key = privateKey;
}
+ /**
+ * Returns <code>true</code> if the specified value is compatible with
+ * this key, and <code>false</code> otherwise.
+ *
+ * @param value the value (<code>null</code> permitted).
+ *
+ * @return A boolean.
+ */
public abstract boolean isCompatibleValue(Object value);
+ /**
+ * Returns the private key for this instance.
+ *
+ * @return The private key.
+ */
protected final int intKey()
{
return key;
}
+ /**
+ * Returns a hash code for the key.
+ *
+ * @return A hash code.
+ */
public final int hashCode()
{
return System.identityHashCode(this);
}
+ /**
+ * Checks this key for equality with an arbitrary object.
+ *
+ * @param other the object (<code>null</code> permitted)
+ *
+ * @return A boolean.
+ */
public final boolean equals(Object other)
{
return this == other;
@@ -96,11 +133,24 @@ public class RenderingHints implements Map, Cloneable
this.v3 = v3;
}
+ /**
+ * Returns <code>true</code> if the specified value is compatible with
+ * this key, and <code>false</code> otherwise.
+ *
+ * @param value the value (<code>null</code> permitted).
+ *
+ * @return A boolean.
+ */
public boolean isCompatibleValue(Object value)
{
return value == v1 || value == v2 || value == v3;
}
+ /**
+ * Returns a string representation of the key.
+ *
+ * @return A string.
+ */
public String toString()
{
return description;
@@ -109,102 +159,345 @@ public class RenderingHints implements Map, Cloneable
private HashMap hintMap = new HashMap();
+ /**
+ * A key for the 'antialiasing' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_ANTIALIAS_OFF}</td>
+ * <td>Render without antialiasing (better speed).</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_ANTIALIAS_ON}</td>
+ * <td>Render with antialiasing (better quality).</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_ANTIALIAS_DEFAULT}</td>
+ * <td>Use the default value for antialiasing.</td>
+ * </tr>
+ * </table>
+ */
public static final Key KEY_ANTIALIASING;
+ /**
+ * This value is for use with the {@link #KEY_ANTIALIASING} key.
+ */
public static final Object VALUE_ANTIALIAS_ON
= "Antialiased rendering mode";
+ /**
+ * This value is for use with the {@link #KEY_ANTIALIASING} key.
+ */
public static final Object VALUE_ANTIALIAS_OFF
= "Nonantialiased rendering mode";
+ /**
+ * This value is for use with the {@link #KEY_ANTIALIASING} key.
+ */
public static final Object VALUE_ANTIALIAS_DEFAULT
= "Default antialiasing rendering mode";
+ /**
+ * A key for the 'rendering' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_RENDER_SPEED}</td>
+ * <td>Prefer speed over quality when rendering.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_RENDER_QUALITY}</td>
+ * <td>Prefer quality over speed when rendering.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_RENDER_DEFAULT}</td>
+ * <td>Use the default value for quality vs. speed when rendering.</td>
+ * </tr>
+ * </table>
+ */
public static final Key KEY_RENDERING;
+ /**
+ * This value is for use with the {@link #KEY_RENDERING} key.
+ */
public static final Object VALUE_RENDER_SPEED
= "Fastest rendering methods";
+ /**
+ * This value is for use with the {@link #KEY_RENDERING} key.
+ */
public static final Object VALUE_RENDER_QUALITY
= "Highest quality rendering methods";
+ /**
+ * This value is for use with the {@link #KEY_RENDERING} key.
+ */
public static final Object VALUE_RENDER_DEFAULT
= "Default rendering methods";
+ /**
+ * A key for the 'dithering' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_DITHER_DISABLE}</td>
+ * <td>Disable dithering.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_DITHER_ENABLE}</td>
+ * <td>Enable dithering.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_DITHER_DEFAULT}</td>
+ * <td>Use the default value for dithering.</td>
+ * </tr>
+ * </table>
+ */
public static final Key KEY_DITHERING;
+ /**
+ * This value is for use with the {@link #KEY_DITHERING} key.
+ */
public static final Object VALUE_DITHER_DISABLE
= "Nondithered rendering mode";
+ /**
+ * This value is for use with the {@link #KEY_DITHERING} key.
+ */
public static final Object VALUE_DITHER_ENABLE
= "Dithered rendering mode";
+ /**
+ * This value is for use with the {@link #KEY_DITHERING} key.
+ */
public static final Object VALUE_DITHER_DEFAULT
= "Default dithering mode";
+ /**
+ * A key for the 'text antialiasing' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_TEXT_ANTIALIAS_ON}</td>
+ * <td>Render text with antialiasing (better quality usually).</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_TEXT_ANTIALIAS_OFF}</td>
+ * <td>Render test without antialiasing (better speed).</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_TEXT_ANTIALIAS_DEFAULT}</td>
+ * <td>Use the default value for text antialiasing.</td>
+ * </tr>
+ * </table>
+ */
public static final Key KEY_TEXT_ANTIALIASING;
+ /**
+ * This value is for use with the {@link #KEY_TEXT_ANTIALIASING} key.
+ */
public static final Object VALUE_TEXT_ANTIALIAS_ON
= "Antialiased text mode";
+ /**
+ * This value is for use with the {@link #KEY_TEXT_ANTIALIASING} key.
+ */
public static final Object VALUE_TEXT_ANTIALIAS_OFF
= "Nonantialiased text mode";
+ /**
+ * This value is for use with the {@link #KEY_TEXT_ANTIALIASING} key.
+ */
public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT
= "Default antialiasing text mode";
+ /**
+ * A key for the 'fractional metrics' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_FRACTIONALMETRICS_OFF}</td>
+ * <td>Render text with fractional metrics off.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_FRACTIONALMETRICS_ON}</td>
+ * <td>Render text with fractional metrics on.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_FRACTIONALMETRICS_DEFAULT}</td>
+ * <td>Use the default value for fractional metrics.</td>
+ * </tr>
+ * </table>
+ */
public static final Key KEY_FRACTIONALMETRICS;
+ /**
+ * This value is for use with the {@link #KEY_FRACTIONALMETRICS} key.
+ */
public static final Object VALUE_FRACTIONALMETRICS_OFF
= "Integer text metrics mode";
+ /**
+ * This value is for use with the {@link #KEY_FRACTIONALMETRICS} key.
+ */
public static final Object VALUE_FRACTIONALMETRICS_ON
= "Fractional text metrics mode";
+ /**
+ * This value is for use with the {@link #KEY_FRACTIONALMETRICS} key.
+ */
public static final Object VALUE_FRACTIONALMETRICS_DEFAULT
= "Default fractional text metrics mode";
+ /**
+ * A key for the 'interpolation' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_INTERPOLATION_NEAREST_NEIGHBOR}</td>
+ * <td>Use nearest neighbour interpolation.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_INTERPOLATION_BILINEAR}</td>
+ * <td>Use bilinear interpolation.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_INTERPOLATION_BICUBIC}</td>
+ * <td>Use bicubic interpolation.</td>
+ * </tr>
+ * </table>
+ */
public static final Key KEY_INTERPOLATION;
+ /**
+ * This value is for use with the {@link #KEY_INTERPOLATION} key.
+ */
public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR
= "Nearest Neighbor image interpolation mode";
+ /**
+ * This value is for use with the {@link #KEY_INTERPOLATION} key.
+ */
public static final Object VALUE_INTERPOLATION_BILINEAR
= "Bilinear image interpolation mode";
+ /**
+ * This value is for use with the {@link #KEY_INTERPOLATION} key.
+ */
public static final Object VALUE_INTERPOLATION_BICUBIC
= "Bicubic image interpolation mode";
+ /**
+ * A key for the 'alpha interpolation' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_ALPHA_INTERPOLATION_SPEED}</td>
+ * <td>Prefer speed over quality.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_ALPHA_INTERPOLATION_QUALITY}</td>
+ * <td>Prefer quality over speed.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_ALPHA_INTERPOLATION_DEFAULT}</td>
+ * <td>Use the default setting.</td>
+ * </tr>
+ * </table>
+ */
public static final Key KEY_ALPHA_INTERPOLATION;
+ /**
+ * This value is for use with the {@link #KEY_ALPHA_INTERPOLATION} key.
+ */
public static final Object VALUE_ALPHA_INTERPOLATION_SPEED
= "Fastest alpha blending methods";
+ /**
+ * This value is for use with the {@link #KEY_ALPHA_INTERPOLATION} key.
+ */
public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY
= "Highest quality alpha blending methods";
+ /**
+ * This value is for use with the {@link #KEY_ALPHA_INTERPOLATION} key.
+ */
public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT
= "Default alpha blending methods";
+ /**
+ * A key for the 'color rendering' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_COLOR_RENDER_SPEED}</td>
+ * <td>Prefer speed over quality.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_COLOR_RENDER_QUALITY}</td>
+ * <td>Prefer quality over speed.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_COLOR_RENDER_DEFAULT}</td>
+ * <td>Use the default setting.</td>
+ * </tr>
+ * </table>
+ */
public static final Key KEY_COLOR_RENDERING;
+ /**
+ * This value is for use with the {@link #KEY_COLOR_RENDERING} key.
+ */
public static final Object VALUE_COLOR_RENDER_SPEED
= "Fastest color rendering mode";
+ /**
+ * This value is for use with the {@link #KEY_COLOR_RENDERING} key.
+ */
public static final Object VALUE_COLOR_RENDER_QUALITY
= "Highest quality color rendering mode";
+ /**
+ * This value is for use with the {@link #KEY_COLOR_RENDERING} key.
+ */
public static final Object VALUE_COLOR_RENDER_DEFAULT
= "Default color rendering mode";
+ /**
+ * A key for the 'stroke control' hint. Permitted values are:
+ * <p>
+ * <table>
+ * <tr>
+ * <td>{@link #VALUE_STROKE_DEFAULT}</td>
+ * <td>Use the default setting.</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_STROKE_NORMALIZE}</td>
+ * <td>XXX</td>
+ * </tr>
+ * <tr>
+ * <td>{@link #VALUE_STROKE_PURE}</td>
+ * <td>XXX</td>
+ * </tr>
+ * </table>
+ */
public static final Key KEY_STROKE_CONTROL;
+ /**
+ * This value is for use with the {@link #KEY_STROKE_CONTROL} key.
+ */
public static final Object VALUE_STROKE_DEFAULT
= "Default stroke normalization";
+ /**
+ * This value is for use with the {@link #KEY_STROKE_CONTROL} key.
+ */
public static final Object VALUE_STROKE_NORMALIZE
= "Normalize strokes for consistent rendering";
+ /**
+ * This value is for use with the {@link #KEY_STROKE_CONTROL} key.
+ */
public static final Object VALUE_STROKE_PURE
= "Pure stroke conversion for accurate paths";
@@ -250,26 +543,59 @@ public class RenderingHints implements Map, Cloneable
VALUE_STROKE_PURE);
}
+ /**
+ * Creates a new collection of hints containing all the (key, value) pairs
+ * in the specified map.
+ *
+ * @param init a map containing a collection of hints (<code>null</code>
+ * permitted).
+ */
public RenderingHints(Map init)
{
- putAll(init);
+ if (init != null)
+ putAll(init);
}
+ /**
+ * Creates a new collection containing a single (key, value) pair.
+ *
+ * @param key the key.
+ * @param value the value.
+ */
public RenderingHints(Key key, Object value)
{
put(key, value);
}
+ /**
+ * Returns the number of hints in the collection.
+ *
+ * @return The number of hints.
+ */
public int size()
{
return hintMap.size();
}
+ /**
+ * Returns <code>true</code> if there are no hints in the collection,
+ * and <code>false</code> otherwise.
+ *
+ * @return A boolean.
+ */
public boolean isEmpty()
{
return hintMap.isEmpty();
}
+ /**
+ * Returns <code>true</code> if the collection of hints contains the
+ * specified key, and <code>false</code> otherwise.
+ *
+ * @param key the key.
+ *
+ * @return A boolean.
+ */
public boolean containsKey(Object key)
{
if (key == null)
@@ -277,16 +603,42 @@ public class RenderingHints implements Map, Cloneable
return hintMap.containsKey((Key) key);
}
+ /**
+ * Returns <code>true</code> if the collection of hints contains the
+ * specified value, and <code>false</code> otherwise.
+ *
+ * @param value the value.
+ *
+ * @return A boolean.
+ */
public boolean containsValue(Object value)
{
return hintMap.containsValue(value);
}
+ /**
+ * Returns the value associated with the specified key.
+ *
+ * @param key the key.
+ *
+ * @return The value.
+ */
public Object get(Object key)
{
return hintMap.get((Key) key);
}
+ /**
+ * Adds a (key, value) pair to the collection of hints (if the
+ * collection already contains the specified key, then the
+ * value is updated).
+ *
+ * @param key the key.
+ * @param value the value.
+ *
+ * @return the previous value of the key or <code>null</code> if the key
+ * didn't have a value yet.
+ */
public Object put(Object key, Object value)
{
if (key == null || value == null)
@@ -296,51 +648,125 @@ public class RenderingHints implements Map, Cloneable
return hintMap.put(key, value);
}
+ /**
+ * Adds all the hints from a collection to this collection.
+ *
+ * @param hints the hint collection.
+ */
public void add(RenderingHints hints)
{
hintMap.putAll(hints);
}
+ /**
+ * Clears all the hints from this collection.
+ */
public void clear()
{
hintMap.clear();
}
+ /**
+ * Removes a hint from the collection.
+ *
+ * @param key the key.
+ *
+ * @return The value that was associated with the key, or <code>null</code> if
+ * the key was not part of the collection
+ *
+ * @throws ClassCastException if the key is not a subclass of
+ * {@link RenderingHints.Key}.
+ */
public Object remove(Object key)
{
- return remove((Key) key);
+ // don't remove the (Key) cast, it is necessary to throw the exception
+ // required by the spec
+ return hintMap.remove((Key) key);
}
+ /**
+ * Adds a collection of (key, value) pairs to the collection.
+ *
+ * @param m a map containing (key, value) items.
+ *
+ * @throws ClassCastException if the map contains a key that is not
+ * a subclass of {@link RenderingHints.Key}.
+ * @throws IllegalArgumentException if the map contains a value that is
+ * not compatible with its key.
+ */
public void putAll(Map m)
{
+ // preprocess map to generate appropriate exceptions
+ Iterator iterator = m.keySet().iterator();
+ while (iterator.hasNext())
+ {
+ Key key = (Key) iterator.next();
+ if (!key.isCompatibleValue(m.get(key)))
+ throw new IllegalArgumentException();
+ }
+ // map is OK, update
hintMap.putAll(m);
}
+ /**
+ * Returns a set containing the keys from this collection.
+ *
+ * @return A set of keys.
+ */
public Set keySet()
{
return hintMap.keySet();
}
+ /**
+ * Returns a collection of the values from this hint collection. The
+ * collection is backed by the <code>RenderingHints</code> instance,
+ * so updates to one will affect the other.
+ *
+ * @return A collection of values.
+ */
public Collection values()
{
return hintMap.values();
}
+ /**
+ * Returns a set of entries from the collection.
+ *
+ * @return A set of entries.
+ */
public Set entrySet()
{
return Collections.unmodifiableSet(hintMap.entrySet());
}
+ /**
+ * Checks this collection for equality with an arbitrary object.
+ *
+ * @param o the object (<code>null</code> permitted)
+ *
+ * @return A boolean.
+ */
public boolean equals(Object o)
{
return hintMap.equals(o);
}
+ /**
+ * Returns a hash code for the collection of hints.
+ *
+ * @return A hash code.
+ */
public int hashCode()
{
return hintMap.hashCode();
}
+ /**
+ * Creates a clone of this instance.
+ *
+ * @return A clone.
+ */
public Object clone()
{
try
@@ -355,6 +781,11 @@ public class RenderingHints implements Map, Cloneable
}
}
+ /**
+ * Returns a string representation of this instance.
+ *
+ * @return A string.
+ */
public String toString()
{
return hintMap.toString();
diff --git a/libjava/java/awt/ScrollPane.java b/libjava/java/awt/ScrollPane.java
index 457df0c0e26..abd5514d8e3 100644
--- a/libjava/java/awt/ScrollPane.java
+++ b/libjava/java/awt/ScrollPane.java
@@ -1,5 +1,5 @@
/* ScrollPane.java -- Scrolling window
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -41,6 +41,7 @@ package java.awt;
import java.awt.event.MouseEvent;
import java.awt.peer.ComponentPeer;
import java.awt.peer.ScrollPanePeer;
+
import javax.accessibility.Accessible;
/**
diff --git a/libjava/java/awt/Scrollbar.java b/libjava/java/awt/Scrollbar.java
index a01dc3ccdc8..7cc97153796 100644
--- a/libjava/java/awt/Scrollbar.java
+++ b/libjava/java/awt/Scrollbar.java
@@ -1,5 +1,6 @@
/* Scrollbar.java -- AWT Scrollbar widget
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,10 +39,11 @@ exception statement from your version. */
package java.awt;
-import java.awt.event.AdjustmentListener;
import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
import java.awt.peer.ScrollbarPeer;
import java.util.EventListener;
+
import javax.accessibility.Accessible;
/**
@@ -123,7 +125,7 @@ private transient boolean valueIsAdjusting = false;
/*
* The number used to generate the name returned by getName.
*/
- private static transient long next_scrollbar_number = 0;
+ private static transient long next_scrollbar_number;
/*************************************************************************/
@@ -363,7 +365,7 @@ getVisible()
* Sets the width of the scrollbar's thumb, in units relative to the
* maximum and minimum value of the scrollbar.
*
- * @param visibileAmount The new visible amount value of the scrollbar.
+ * @param visibleAmount The new visible amount value of the scrollbar.
*/
public void
setVisibleAmount(int visibleAmount)
diff --git a/libjava/java/awt/Shape.java b/libjava/java/awt/Shape.java
index 8d61c4a9a88..47c97192a17 100644
--- a/libjava/java/awt/Shape.java
+++ b/libjava/java/awt/Shape.java
@@ -57,8 +57,8 @@ import java.awt.geom.Rectangle2D;
* @author Aaron M. Renn <arenn@urbanophile.com>
* @see PathIterator
* @see AffineTransform
- * @see FlatteningPathIterator
- * @see GeneralPath
+ * @see java.awt.geom.FlatteningPathIterator
+ * @see java.awt.geom.GeneralPath
* @since 1.0
* @status updated to 1.4
*/
@@ -109,15 +109,15 @@ public interface Shape
* Test if a high-precision rectangle intersects the shape. This is true
* if any point in the rectangle is in the shape, with the caveat that the
* operation may include high probability estimates when the actual
- * calculation is prohibitively expensive. The {@link Area} class can
- * be used for more precise answers.
+ * calculation is prohibitively expensive. The {@link java.awt.geom.Area}
+ * class can be used for more precise answers.
*
* @param x the x coordinate of the rectangle
* @param y the y coordinate of the rectangle
* @param w the width of the rectangle, undefined results if negative
* @param h the height of the rectangle, undefined results if negative
* @return true if the rectangle intersects this shape
- * @see Area
+ * @see java.awt.geom.Area
* @since 1.2
*/
boolean intersects(double x, double y, double w, double h);
@@ -126,8 +126,8 @@ public interface Shape
* Test if a high-precision rectangle intersects the shape. This is true
* if any point in the rectangle is in the shape, with the caveat that the
* operation may include high probability estimates when the actual
- * calculation is prohibitively expensive. The {@link Area} class can
- * be used for more precise answers.
+ * calculation is prohibitively expensive. The {@link java.awt.geom.Area}
+ * class can be used for more precise answers.
*
* @param r the rectangle
* @return true if the rectangle intersects this shape
@@ -141,15 +141,15 @@ public interface Shape
* Test if a high-precision rectangle lies completely in the shape. This is
* true if all points in the rectangle are in the shape, with the caveat
* that the operation may include high probability estimates when the actual
- * calculation is prohibitively expensive. The {@link Area} class can
- * be used for more precise answers.
+ * calculation is prohibitively expensive. The {@link java.awt.geom.Area}
+ * class can be used for more precise answers.
*
* @param x the x coordinate of the rectangle
* @param y the y coordinate of the rectangle
* @param w the width of the rectangle, undefined results if negative
* @param h the height of the rectangle, undefined results if negative
* @return true if the rectangle is contained in this shape
- * @see Area
+ * @see java.awt.geom.Area
* @since 1.2
*/
boolean contains(double x, double y, double w, double h);
@@ -158,8 +158,8 @@ public interface Shape
* Test if a high-precision rectangle lies completely in the shape. This is
* true if all points in the rectangle are in the shape, with the caveat
* that the operation may include high probability estimates when the actual
- * calculation is prohibitively expensive. The {@link Area} class can
- * be used for more precise answers.
+ * calculation is prohibitively expensive. The {@link java.awt.geom.Area}
+ * class can be used for more precise answers.
*
* @param r the rectangle
* @return true if the rectangle is contained in this shape
@@ -195,7 +195,7 @@ public interface Shape
* iterations from future changes to the boundary, and document this fact.
*
* @param transform an optional transform to apply to the iterator
- * @param double the maximum distance for deviation from the real boundary
+ * @param flatness the maximum distance for deviation from the real boundary
* @return a new iterator over the boundary
* @since 1.2
*/
diff --git a/libjava/java/awt/SystemColor.java b/libjava/java/awt/SystemColor.java
index 5217677b722..3428fba3cc5 100644
--- a/libjava/java/awt/SystemColor.java
+++ b/libjava/java/awt/SystemColor.java
@@ -1,5 +1,5 @@
/* SystemColor.java -- access dynamic system color values
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,9 +38,9 @@ exception statement from your version. */
package java.awt;
-import java.awt.image.ColorModel;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
+import java.awt.image.ColorModel;
import java.io.Serializable;
/**
@@ -72,7 +72,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the desktop color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #desktop
*/
@@ -80,7 +80,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the active caption color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #activeCaption
*/
@@ -88,7 +88,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the active caption text color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #activeCaptionText
*/
@@ -96,7 +96,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the active caption border color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #activeCaptionBorder
*/
@@ -104,7 +104,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the inactive caption color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #inactiveCaption
*/
@@ -112,7 +112,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the inactive caption text color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #inactiveCaptionText
*/
@@ -120,7 +120,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the inactive caption border color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #inactiveCaptionBorder
*/
@@ -128,7 +128,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the window background color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #window
*/
@@ -136,7 +136,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the window border color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #windowBorder
*/
@@ -144,7 +144,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the window text color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #windowText
*/
@@ -152,7 +152,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the menu background color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #menu
*/
@@ -160,7 +160,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the menu text color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #menuText
*/
@@ -168,7 +168,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the text background color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #text
*/
@@ -176,7 +176,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the text foreground color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #textText
*/
@@ -184,7 +184,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the highlighted text background color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #textHighlight
*/
@@ -192,7 +192,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the highlighted text foreground color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #textHighlightText
*/
@@ -200,7 +200,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the inactive text foreground color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #textInactiveText
*/
@@ -208,7 +208,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the control background color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #control
*/
@@ -216,7 +216,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the control text color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #controlText
*/
@@ -224,7 +224,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the highlighted control background color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #controlHighlight
*/
@@ -232,7 +232,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the lightly highlighted control background color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #controlLtHighlight
*/
@@ -240,7 +240,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the shadowed control background color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #controlShadow
*/
@@ -248,7 +248,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the darkly shadowed control background color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #controlDkShadow
*/
@@ -256,7 +256,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the scrollbar background color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #scrollbar
*/
@@ -264,7 +264,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the info background color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #info
*/
@@ -272,7 +272,7 @@ public final class SystemColor extends Color implements Serializable
/**
* Array index of the info text color. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*
* @see #infoText
*/
@@ -280,7 +280,7 @@ public final class SystemColor extends Color implements Serializable
/**
* The number of system colors. Used by
- * {@link Toolkit#loadSystemColors()}.
+ * {@link Toolkit#loadSystemColors(int[])}.
*/
public static final int NUM_COLORS = 26;
diff --git a/libjava/java/awt/TextArea.java b/libjava/java/awt/TextArea.java
index 6355376df52..9efc7754a20 100644
--- a/libjava/java/awt/TextArea.java
+++ b/libjava/java/awt/TextArea.java
@@ -1,48 +1,52 @@
/* TextArea.java -- A multi-line text entry component
Copyright (C) 1999, 2004 Free Software Foundation, Inc.
- This file is part of GNU Classpath.
-
- GNU Classpath is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GNU Classpath is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNU Classpath; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 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. */
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.awt;
+import java.awt.event.KeyEvent;
import java.awt.peer.ComponentPeer;
import java.awt.peer.TextAreaPeer;
-import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleStateSet;
+
/**
* A TextArea is a text component capable of displaying multiple lines
@@ -100,7 +104,7 @@ public class TextArea extends TextComponent implements java.io.Serializable
/*
* The number used to generate the name returned by getName.
*/
- private static transient long next_text_number = 0;
+ private static transient long next_text_number;
/**
* Initialize a new instance of <code>TextArea</code> that is empty.
@@ -596,4 +600,21 @@ public class TextArea extends TextComponent implements java.io.Serializable
{
return next_text_number++;
}
+
+ protected class AccessibleAWTTextArea extends AccessibleAWTTextComponent
+ {
+ protected AccessibleAWTTextArea()
+ {
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ return super.getAccessibleStateSet();
+ }
+ }
+
+ public AccessibleContext getAccessibleContext()
+ {
+ return new AccessibleAWTTextArea();
+ }
}
diff --git a/libjava/java/awt/TextComponent.java b/libjava/java/awt/TextComponent.java
index 9cdb507f30a..8f9f875acf3 100644
--- a/libjava/java/awt/TextComponent.java
+++ b/libjava/java/awt/TextComponent.java
@@ -42,8 +42,16 @@ import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import java.awt.peer.TextComponentPeer;
import java.io.Serializable;
+import java.text.BreakIterator;
import java.util.EventListener;
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleState;
+import javax.accessibility.AccessibleStateSet;
+import javax.accessibility.AccessibleText;
+import javax.swing.text.AttributeSet;
+
/**
* This class provides common functionality for widgets than
* contain text.
@@ -51,7 +59,7 @@ import java.util.EventListener;
* @author Aaron M. Renn (arenn@urbanophile.com)
*/
public class TextComponent extends Component
- implements Serializable
+ implements Serializable, Accessible
{
/*
@@ -90,6 +98,219 @@ private String text;
*/
protected transient TextListener textListener;
+ protected class AccessibleAWTTextComponent
+ extends AccessibleAWTComponent
+ implements AccessibleText, TextListener
+ {
+ // Constructor
+ // Adds a listener for tracking caret changes
+ public AccessibleAWTTextComponent()
+ {
+ TextComponent.this.addTextListener(this);
+ }
+
+ public AccessibleRole getAccessibleRole()
+ {
+ return AccessibleRole.TEXT;
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ // TODO: Docs say PropertyChangeEvent will fire if this state changes.
+ // That means that the event has to fire when editable changes.
+ AccessibleStateSet ss = super.getAccessibleStateSet();
+ if (editable)
+ ss.add(AccessibleState.EDITABLE);
+ return ss;
+ }
+
+ public AccessibleText getAccessibleText()
+ {
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getIndexAtPoint(java.awt.Point)
+ */
+ public int getIndexAtPoint(Point point)
+ {
+ return TextComponent.this.getIndexAtPoint(point);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getCharacterBounds(int)
+ */
+ public Rectangle getCharacterBounds(int index)
+ {
+ return TextComponent.this.getCharacterBounds(index);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getCharCount()
+ */
+ public int getCharCount()
+ {
+ return text.length();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getCaretPosition()
+ */
+ public int getCaretPosition()
+ {
+ return TextComponent.this.getCaretPosition();
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getAtIndex(int, int)
+ */
+ public String getAtIndex(int part, int index)
+ {
+ if (index < 0 || index >= text.length())
+ return null;
+ BreakIterator it = null;
+ switch (part)
+ {
+ case CHARACTER:
+ return text.substring(index, index + 1);
+ case WORD:
+ it = BreakIterator.getWordInstance();
+ break;
+ case SENTENCE:
+ it = BreakIterator.getSentenceInstance();
+ break;
+ default:
+ return null;
+ }
+ it.setText(text);
+ int start = index;
+ if (!it.isBoundary(index))
+ start = it.preceding(index);
+ int end = it.following(index);
+ if (end == -1)
+ return text.substring(index);
+ else
+ return text.substring(index, end);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getAfterIndex(int, int)
+ */
+ public String getAfterIndex(int part, int index) {
+ if (index < 0 || index >= text.length())
+ return null;
+ BreakIterator it = null;
+ switch (part)
+ {
+ case CHARACTER:
+ return text.substring(index, index + 1);
+ case WORD:
+ it = BreakIterator.getWordInstance();
+ break;
+ case SENTENCE:
+ it = BreakIterator.getSentenceInstance();
+ break;
+ default:
+ return null;
+ }
+ it.setText(text);
+ int start = index;
+ if (!it.isBoundary(index))
+ start = it.following(index);
+ // Make sure there was a complete unit. I.e. if index is in the middle
+ // of a word, return null if there is no word after the that one.
+ if (start == -1)
+ return null;
+ int end = it.following(start);
+ if (end == -1)
+ return text.substring(index);
+ else
+ return text.substring(index, end);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getBeforeIndex(int, int)
+ */
+ public String getBeforeIndex(int part, int index)
+ {
+ if (index < 1 || index >= text.length())
+ return null;
+ BreakIterator it = null;
+ switch (part)
+ {
+ case CHARACTER:
+ return text.substring(index - 1, index);
+ case WORD:
+ it = BreakIterator.getWordInstance();
+ break;
+ case SENTENCE:
+ it = BreakIterator.getSentenceInstance();
+ break;
+ default:
+ return null;
+ }
+ it.setText(text);
+ int end = index;
+ if (!it.isBoundary(index))
+ end = it.preceding(index);
+ // Make sure there was a complete unit. I.e. if index is in the middle
+ // of a word, return null if there is no word before that one.
+ if (end == -1)
+ return null;
+ int start = it.preceding(end);
+ if (start == -1)
+ return text.substring(0, end);
+ else
+ return text.substring(start, end);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getCharacterAttribute(int)
+ */
+ public AttributeSet getCharacterAttribute(int index)
+ {
+ // FIXME: I suspect this really gets filled in by subclasses.
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getSelectionStart()
+ */
+ public int getSelectionStart() {
+ // TODO Auto-generated method stub
+ return selectionStart;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getSelectionEnd()
+ */
+ public int getSelectionEnd()
+ {
+ return selectionEnd;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.accessibility.AccessibleText#getSelectedText()
+ */
+ public String getSelectedText()
+ {
+ if (selectionEnd - selectionStart > 0)
+ return text.substring(selectionStart, selectionEnd);
+ else
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.event.TextListener#textValueChanged(java.awt.event.TextEvent)
+ */
+ public void textValueChanged(TextEvent event)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ }
+
/*************************************************************************/
/*
@@ -468,5 +689,30 @@ paramString()
{
return (TextListener[]) getListeners (TextListener.class);
}
+
+ /*******************************/
+ // Provide AccessibleAWTTextComponent access to several peer functions that
+ // aren't publicly exposed.
+ private synchronized int
+ getIndexAtPoint(Point p)
+ {
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ return tcp.getIndexAtPoint(p.x, p.y);
+ return -1;
+ }
+
+ private synchronized Rectangle
+ getCharacterBounds(int i)
+ {
+ TextComponentPeer tcp = (TextComponentPeer)getPeer();
+ if (tcp != null)
+ return tcp.getCharacterBounds(i);
+ return null;
+ }
+
+
+
+
} // class TextComponent
diff --git a/libjava/java/awt/TextField.java b/libjava/java/awt/TextField.java
index 1a783e27a79..5c84aab0965 100644
--- a/libjava/java/awt/TextField.java
+++ b/libjava/java/awt/TextField.java
@@ -1,5 +1,5 @@
/* TextField.java -- A one line text entry field
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,10 +40,13 @@ package java.awt;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.awt.peer.TextFieldPeer;
import java.awt.peer.ComponentPeer;
+import java.awt.peer.TextFieldPeer;
import java.util.EventListener;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleStateSet;
+
/**
* This class implements a single line text entry field widget
*
@@ -517,4 +520,22 @@ paramString()
{
return (ActionListener[]) getListeners (ActionListener.class);
}
+
+ protected class AccessibleAWTTextField extends AccessibleAWTTextComponent
+ {
+ protected AccessibleAWTTextField()
+ {
+ }
+
+ public AccessibleStateSet getAccessibleStateSet()
+ {
+ return super.getAccessibleStateSet();
+ }
+ }
+
+ public AccessibleContext getAccessibleContext()
+ {
+ return new AccessibleAWTTextField();
+ }
+
} // class TextField
diff --git a/libjava/java/awt/Toolkit.java b/libjava/java/awt/Toolkit.java
index 2ee3f508983..504572a2d5b 100644
--- a/libjava/java/awt/Toolkit.java
+++ b/libjava/java/awt/Toolkit.java
@@ -53,8 +53,8 @@ import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.awt.peer.ButtonPeer;
import java.awt.peer.CanvasPeer;
-import java.awt.peer.CheckboxPeer;
import java.awt.peer.CheckboxMenuItemPeer;
+import java.awt.peer.CheckboxPeer;
import java.awt.peer.ChoicePeer;
import java.awt.peer.DialogPeer;
import java.awt.peer.FileDialogPeer;
@@ -63,13 +63,13 @@ import java.awt.peer.FramePeer;
import java.awt.peer.LabelPeer;
import java.awt.peer.LightweightPeer;
import java.awt.peer.ListPeer;
-import java.awt.peer.MenuPeer;
import java.awt.peer.MenuBarPeer;
import java.awt.peer.MenuItemPeer;
+import java.awt.peer.MenuPeer;
import java.awt.peer.PanelPeer;
import java.awt.peer.PopupMenuPeer;
-import java.awt.peer.ScrollbarPeer;
import java.awt.peer.ScrollPanePeer;
+import java.awt.peer.ScrollbarPeer;
import java.awt.peer.TextAreaPeer;
import java.awt.peer.TextFieldPeer;
import java.awt.peer.WindowPeer;
@@ -371,8 +371,8 @@ public abstract class Toolkit
* should override this method and provide real system colors for the
* native GUI platform.
*
- * @param colors The array to copy the system colors into.
- * It must be at least 26 elements.
+ * @param systemColors The array to copy the system colors into.
+ * It must be at least 26 elements.
*
* @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
*
diff --git a/libjava/java/awt/Window.java b/libjava/java/awt/Window.java
index 7397a1c1c33..d084bb4350b 100644
--- a/libjava/java/awt/Window.java
+++ b/libjava/java/awt/Window.java
@@ -1,5 +1,5 @@
/* Window.java --
- Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation
+ Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -48,11 +48,12 @@ import java.awt.event.WindowStateListener;
import java.awt.peer.WindowPeer;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
-import java.util.Iterator;
import java.util.EventListener;
+import java.util.Iterator;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Vector;
+
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
@@ -141,7 +142,7 @@ public class Window extends Container implements Accessible
* Initializes a new instance of <code>Window</code> with the specified
* parent. The window will initially be invisible.
*
- * @param parent The owning <code>Frame</code> of this window.
+ * @param owner The owning <code>Frame</code> of this window.
*
* @exception IllegalArgumentException If the owner's GraphicsConfiguration
* is not from a screen device, or if owner is null; this exception is always
@@ -291,7 +292,7 @@ public class Window extends Container implements Accessible
initialFocusOwner = policy.getInitialComponent (this);
if (initialFocusOwner != null)
- initialFocusOwner.requestFocusInWindow (false);
+ initialFocusOwner.requestFocusInWindow ();
shown = true;
}
@@ -604,7 +605,7 @@ public class Window extends Container implements Accessible
* <code>processWindowEvent()</code> is called to process the event,
* otherwise the superclass version of this method is invoked.
*
- * @param event The event to process.
+ * @param evt The event to process.
*/
protected void processEvent(AWTEvent evt)
{
@@ -620,7 +621,7 @@ public class Window extends Container implements Accessible
* invoked if it is enabled via <code>enableEvents()</code> or if
* a listener has been added.
*
- * @param event The event to process.
+ * @param evt The event to process.
*/
protected void processWindowEvent(WindowEvent evt)
{
@@ -710,7 +711,7 @@ public class Window extends Container implements Accessible
/**
* Post a Java 1.0 event to the event queue.
*
- * @param event The event to post.
+ * @param e The event to post.
*
* @deprecated
*/
diff --git a/libjava/java/awt/color/ICC_ColorSpace.java b/libjava/java/awt/color/ICC_ColorSpace.java
index 2ed247f52b0..5cc526adb7a 100644
--- a/libjava/java/awt/color/ICC_ColorSpace.java
+++ b/libjava/java/awt/color/ICC_ColorSpace.java
@@ -1,5 +1,5 @@
/* ICC_ColorSpace.java -- the canonical color space implementation
- Copyright (C) 2000, 2002 Free Software Foundation
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -38,9 +38,44 @@ exception statement from your version. */
package java.awt.color;
+import gnu.java.awt.color.CieXyzConverter;
+import gnu.java.awt.color.ClutProfileConverter;
+import gnu.java.awt.color.ColorSpaceConverter;
+import gnu.java.awt.color.GrayProfileConverter;
+import gnu.java.awt.color.GrayScaleConverter;
+import gnu.java.awt.color.LinearRGBConverter;
+import gnu.java.awt.color.PyccConverter;
+import gnu.java.awt.color.RgbProfileConverter;
+import gnu.java.awt.color.SrgbConverter;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
/**
- * NEEDS DOCUMENTATION
+ * ICC_ColorSpace - an implementation of ColorSpace
+ *
+ * While an ICC_Profile class abstracts the data in an ICC profile file
+ * an ICC_ColorSpace performs the color space conversions defined by
+ * an ICC_Profile instance.
+ *
+ * Typically, an ICC_Profile will either be created using getInstance,
+ * either from the built-in colorspaces, or from an ICC profile file.
+ * Then a ICC_Colorspace will be used to perform transforms from the
+ * device colorspace to and from the profile color space.
+ *
+ * The PCS used by ColorSpace is CIE XYZ relative a D50 white point.
+ * (Profiles using a CIE Lab PCS will have their input and output converted
+ * to D50 CIE XYZ accordingly.
*
+ * Note that a valid profile may not contain transforms in both directions,
+ * in which case the output may be undefined.
+ * All built-in colorspaces have bidirectional transforms, but developers
+ * using an ICC profile file may want to check the profile class using
+ * the ICC_Profile.getProfileClass() method. Input class profiles are
+ * guaranteed to have transforms to the PCS, output class profiles are
+ * guaranteed to have transforms from the PCS to device space.
+ *
+ * @author Sven de Marothy
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
* @since 1.2
*/
@@ -82,6 +117,13 @@ public class ICC_ColorSpace extends ColorSpace
private boolean needScaleInit;
/**
+ * Tells us if the PCS is CIE LAB (must be CIEXYZ otherwise)
+ */
+ private transient int type;
+ private transient int nComponents;
+ private transient ColorSpaceConverter converter;
+
+ /**
* Constructs a new ICC_ColorSpace from an ICC_Profile object.
*
* @exception IllegalArgumentException If profile is inappropriate for
@@ -89,10 +131,18 @@ public class ICC_ColorSpace extends ColorSpace
*/
public ICC_ColorSpace(ICC_Profile profile)
{
- super(CS_sRGB, profile.getNumComponents());
+ super(profile.getColorSpaceType(), profile.getNumComponents());
+
+ converter = getConverter(profile);
thisProfile = profile;
+ nComponents = profile.getNumComponents();
+ type = profile.getColorSpaceType();
+ makeArrays();
}
+ /**
+ * Return the profile
+ */
public ICC_Profile getProfile()
{
return thisProfile;
@@ -107,11 +157,7 @@ public class ICC_ColorSpace extends ColorSpace
*/
public float[] toRGB(float[] colorvalue)
{
- if (colorvalue.length < numComponents)
- throw new IllegalArgumentException ();
-
- // FIXME: Always assumes sRGB:
- return colorvalue;
+ return converter.toRGB(colorvalue);
}
/**
@@ -123,11 +169,7 @@ public class ICC_ColorSpace extends ColorSpace
*/
public float[] fromRGB(float[] rgbvalue)
{
- if (rgbvalue.length < 3)
- throw new IllegalArgumentException ();
-
- // FIXME: Always assumes sRGB:
- return rgbvalue;
+ return converter.fromRGB(rgbvalue);
}
/**
@@ -139,8 +181,7 @@ public class ICC_ColorSpace extends ColorSpace
*/
public float[] toCIEXYZ(float[] colorvalue)
{
- // FIXME: Not implemented
- throw new UnsupportedOperationException();
+ return converter.toCIEXYZ(colorvalue);
}
/**
@@ -152,8 +193,12 @@ public class ICC_ColorSpace extends ColorSpace
*/
public float[] fromCIEXYZ(float[] colorvalue)
{
- // FIXME: Not implemented
- throw new UnsupportedOperationException();
+ return converter.fromCIEXYZ(colorvalue);
+ }
+
+ public boolean isCS_sRGB()
+ {
+ return converter instanceof SrgbConverter;
}
/**
@@ -167,9 +212,11 @@ public class ICC_ColorSpace extends ColorSpace
*/
public float getMinValue(int idx)
{
- if (type == TYPE_Lab && (idx == 1 || idx == 2))
- return -128;
- if (idx < 0 || idx >= numComponents)
+ // FIXME: Not 100% certain of this.
+ if (type == ColorSpace.TYPE_Lab && (idx == 1 || idx == 2))
+ return -128f;
+
+ if (idx < 0 || idx >= nComponents)
throw new IllegalArgumentException();
return 0;
}
@@ -185,17 +232,83 @@ public class ICC_ColorSpace extends ColorSpace
*/
public float getMaxValue(int idx)
{
- if (type == TYPE_XYZ && idx >= 0 && idx <= 2)
+ if (type == ColorSpace.TYPE_XYZ && idx >= 0 && idx <= 2)
return 1 + 32767 / 32768f;
- else if (type == TYPE_Lab)
+ else if (type == ColorSpace.TYPE_Lab)
{
- if (idx == 0)
- return 100;
- if (idx == 1 || idx == 2)
- return 127;
+ if (idx == 0)
+ return 100;
+ if (idx == 1 || idx == 2)
+ return 127;
}
- if (idx < 0 || idx >= numComponents)
+ if (idx < 0 || idx >= nComponents)
throw new IllegalArgumentException();
return 1;
}
+
+ /**
+ * Returns a colorspace converter suitable for a given profile
+ */
+ private ColorSpaceConverter getConverter(ICC_Profile profile)
+ {
+ ColorSpaceConverter converter;
+ switch (profile.isPredefined())
+ {
+ case CS_sRGB:
+ converter = new SrgbConverter();
+ break;
+ case CS_CIEXYZ:
+ converter = new CieXyzConverter();
+ break;
+ case CS_GRAY:
+ converter = new GrayScaleConverter();
+ break;
+ case CS_LINEAR_RGB:
+ converter = new LinearRGBConverter();
+ break;
+ case CS_PYCC:
+ converter = new PyccConverter();
+ break;
+ default:
+ if (profile instanceof ICC_ProfileRGB)
+ converter = new RgbProfileConverter((ICC_ProfileRGB) profile);
+ else if (profile instanceof ICC_ProfileGray)
+ converter = new GrayProfileConverter((ICC_ProfileGray) profile);
+ else
+ converter = new ClutProfileConverter(profile);
+ break;
+ }
+ return converter;
+ }
+
+ /**
+ * Serialization compatibility requires these variable to be set,
+ * although we don't use them. Perhaps we should?
+ */
+ private void makeArrays()
+ {
+ minVal = new float[nComponents];
+ maxVal = new float[nComponents];
+
+ invDiffMinMax = diffMinMax = null;
+ for (int i = 0; i < nComponents; i++)
+ {
+ minVal[i] = getMinValue(i);
+ maxVal[i] = getMaxValue(i);
+ }
+ needScaleInit = true;
+ }
+
+ /**
+ * Deserializes the object
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ // set up objects
+ converter = getConverter(thisProfile);
+ nComponents = thisProfile.getNumComponents();
+ type = thisProfile.getColorSpaceType();
+ }
} // class ICC_ColorSpace
diff --git a/libjava/java/awt/color/ICC_Profile.java b/libjava/java/awt/color/ICC_Profile.java
index eb534ebffca..79aa886ec49 100644
--- a/libjava/java/awt/color/ICC_Profile.java
+++ b/libjava/java/awt/color/ICC_Profile.java
@@ -1,5 +1,5 @@
/* ICC_Profile.java -- color space profiling
- Copyright (C) 2000, 2002 Free Software Foundation
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -38,18 +38,47 @@ exception statement from your version. */
package java.awt.color;
+import gnu.java.awt.color.ProfileHeader;
+import gnu.java.awt.color.TagEntry;
+
import java.io.FileInputStream;
import java.io.FileOutputStream;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.OutputStream;
import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.Enumeration;
+import java.util.Hashtable;
/**
- * STUBBED
+ * ICC Profile - represents an ICC Color profile.
+ * The ICC profile format is a standard file format which maps the transform
+ * from a device color space to a standard Profile Color Space (PCS), which
+ * can either be CIE L*a*b or CIE XYZ.
+ * (With the exception of device link profiles which map from one device space
+ * to another)
+ *
+ * ICC profiles calibrated to specific input/output devices are used when color
+ * fidelity is of importance.
+ *
+ * An instance of ICC_Profile can be created using the getInstance() methods,
+ * either using one of the predefined color spaces enumerated in ColorSpace,
+ * or from an ICC profile file, or from an input stream.
+ *
+ * An ICC_ColorSpace object can then be created to transform color values
+ * through the profile.
+ *
+ * The ICC_Profile class implements the version 2 format specified by
+ * International Color Consortium Specification ICC.1:1998-09,
+ * and its addendum ICC.1A:1999-04, April 1999
+ * (available at www.color.org)
+ *
+ * @author Sven de Marothy
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
* @since 1.2
*/
@@ -60,6 +89,9 @@ public class ICC_Profile implements Serializable
*/
private static final long serialVersionUID = -3938515861990936766L;
+ /**
+ * ICC Profile classes
+ */
public static final int CLASS_INPUT = 0;
public static final int CLASS_DISPLAY = 1;
public static final int CLASS_OUTPUT = 2;
@@ -68,92 +100,111 @@ public class ICC_Profile implements Serializable
public static final int CLASS_ABSTRACT = 5;
public static final int CLASS_NAMEDCOLOR = 6;
- public static final int icSigXYZData = 1482250784;
- public static final int icSigLabData = 1281450528;
- public static final int icSigLuvData = 1282766368;
- public static final int icSigYCbCrData = 1497588338;
- public static final int icSigYxyData = 1501067552;
- public static final int icSigRgbData = 1380401696;
- public static final int icSigGrayData = 1196573017;
- public static final int icSigHsvData = 1213421088;
- public static final int icSigHlsData = 1212961568;
- public static final int icSigCmykData = 1129142603;
- public static final int icSigCmyData = 1129142560;
- public static final int icSigSpace2CLR = 843271250;
- public static final int icSigSpace3CLR = 860048466;
- public static final int icSigSpace4CLR = 876825682;
- public static final int icSigSpace5CLR = 893602898;
- public static final int icSigSpace6CLR = 910380114;
- public static final int icSigSpace7CLR = 927157330;
- public static final int icSigSpace8CLR = 943934546;
- public static final int icSigSpace9CLR = 960711762;
- public static final int icSigSpaceACLR = 1094929490;
- public static final int icSigSpaceBCLR = 1111706706;
- public static final int icSigSpaceCCLR = 1128483922;
- public static final int icSigSpaceDCLR = 1145261138;
- public static final int icSigSpaceECLR = 1162038354;
- public static final int icSigSpaceFCLR = 1178815570;
-
- public static final int icSigInputClass = 1935896178;
- public static final int icSigDisplayClass = 1835955314;
- public static final int icSigOutputClass = 1886549106;
- public static final int icSigLinkClass = 1818848875;
- public static final int icSigAbstractClass = 1633842036;
- public static final int icSigColorSpaceClass = 1936744803;
- public static final int icSigNamedColorClass = 1852662636;
+ /**
+ * ICC Profile class signatures
+ */
+ public static final int icSigInputClass = 0x73636e72; // 'scnr'
+ public static final int icSigDisplayClass = 0x6d6e7472; // 'mntr'
+ public static final int icSigOutputClass = 0x70727472; // 'prtr'
+ public static final int icSigLinkClass = 0x6c696e6b; // 'link'
+ public static final int icSigColorSpaceClass = 0x73706163; // 'spac'
+ public static final int icSigAbstractClass = 0x61627374; // 'abst'
+ public static final int icSigNamedColorClass = 0x6e6d636c; // 'nmcl'
+
+ /**
+ * Color space signatures
+ */
+ public static final int icSigXYZData = 0x58595A20; // 'XYZ '
+ public static final int icSigLabData = 0x4C616220; // 'Lab '
+ public static final int icSigLuvData = 0x4C757620; // 'Luv '
+ public static final int icSigYCbCrData = 0x59436272; // 'YCbr'
+ public static final int icSigYxyData = 0x59787920; // 'Yxy '
+ public static final int icSigRgbData = 0x52474220; // 'RGB '
+ public static final int icSigGrayData = 0x47524159; // 'GRAY'
+ public static final int icSigHsvData = 0x48535620; // 'HSV '
+ public static final int icSigHlsData = 0x484C5320; // 'HLS '
+ public static final int icSigCmykData = 0x434D594B; // 'CMYK'
+ public static final int icSigCmyData = 0x434D5920; // 'CMY '
+ public static final int icSigSpace2CLR = 0x32434C52; // '2CLR'
+ public static final int icSigSpace3CLR = 0x33434C52; // '3CLR'
+ public static final int icSigSpace4CLR = 0x34434C52; // '4CLR'
+ public static final int icSigSpace5CLR = 0x35434C52; // '5CLR'
+ public static final int icSigSpace6CLR = 0x36434C52; // '6CLR'
+ public static final int icSigSpace7CLR = 0x37434C52; // '7CLR'
+ public static final int icSigSpace8CLR = 0x38434C52; // '8CLR'
+ public static final int icSigSpace9CLR = 0x39434C52; // '9CLR'
+ public static final int icSigSpaceACLR = 0x41434C52; // 'ACLR'
+ public static final int icSigSpaceBCLR = 0x42434C52; // 'BCLR'
+ public static final int icSigSpaceCCLR = 0x43434C52; // 'CCLR'
+ public static final int icSigSpaceDCLR = 0x44434C52; // 'DCLR'
+ public static final int icSigSpaceECLR = 0x45434C52; // 'ECLR'
+ public static final int icSigSpaceFCLR = 0x46434C52; // 'FCLR'
+ /**
+ * Rendering intents
+ */
public static final int icPerceptual = 0;
public static final int icRelativeColorimetric = 1;
public static final int icSaturation = 2;
public static final int icAbsoluteColorimetric = 3;
- public static final int icSigHead = 1751474532;
- public static final int icSigAToB0Tag = 1093812784;
- public static final int icSigAToB1Tag = 1093812785;
- public static final int icSigAToB2Tag = 1093812786;
- public static final int icSigBlueColorantTag = 1649957210;
- public static final int icSigBlueTRCTag = 1649693251;
- public static final int icSigBToA0Tag = 1110589744;
- public static final int icSigBToA1Tag = 1110589745;
- public static final int icSigBToA2Tag = 1110589746;
- public static final int icSigCalibrationDateTimeTag = 1667329140;
- public static final int icSigCharTargetTag = 1952543335;
- public static final int icSigCopyrightTag = 1668313716;
- public static final int icSigCrdInfoTag = 1668441193;
- public static final int icSigDeviceMfgDescTag = 1684893284;
- public static final int icSigDeviceModelDescTag = 1684890724;
- public static final int icSigDeviceSettingsTag = 1684371059;
- public static final int icSigGamutTag = 1734438260;
- public static final int icSigGrayTRCTag = 1800688195;
- public static final int icSigGreenColorantTag = 1733843290;
- public static final int icSigGreenTRCTag = 1733579331;
- public static final int icSigLuminanceTag = 1819635049;
- public static final int icSigMeasurementTag = 1835360627;
- public static final int icSigMediaBlackPointTag = 1651208308;
- public static final int icSigMediaWhitePointTag = 2004119668;
- public static final int icSigNamedColor2Tag = 1852009522;
- public static final int icSigOutputResponseTag = 1919251312;
- public static final int icSigPreview0Tag = 1886545200;
- public static final int icSigPreview1Tag = 1886545201;
- public static final int icSigPreview2Tag = 1886545202;
- public static final int icSigProfileDescriptionTag = 1684370275;
- public static final int icSigProfileSequenceDescTag = 1886610801;
- public static final int icSigPs2CRD0Tag = 1886610480;
- public static final int icSigPs2CRD1Tag = 1886610481;
- public static final int icSigPs2CRD2Tag = 1886610482;
- public static final int icSigPs2CRD3Tag = 1886610483;
- public static final int icSigPs2CSATag = 1886597747;
- public static final int icSigPs2RenderingIntentTag = 1886597737;
- public static final int icSigRedColorantTag = 1918392666;
- public static final int icSigRedTRCTag = 1918128707;
- public static final int icSigScreeningDescTag = 1935897188;
- public static final int icSigScreeningTag = 1935897198;
- public static final int icSigTechnologyTag = 1952801640;
- public static final int icSigUcrBgTag = 1650877472;
- public static final int icSigViewingCondDescTag = 1987405156;
- public static final int icSigViewingConditionsTag = 1986618743;
- public static final int icSigChromaticityTag = 1667789421;
+ /**
+ * Tag signatures
+ */
+ public static final int icSigAToB0Tag = 0x41324230; // 'A2B0'
+ public static final int icSigAToB1Tag = 0x41324231; // 'A2B1'
+ public static final int icSigAToB2Tag = 0x41324232; // 'A2B2'
+ public static final int icSigBlueColorantTag = 0x6258595A; // 'bXYZ'
+ public static final int icSigBlueTRCTag = 0x62545243; // 'bTRC'
+ public static final int icSigBToA0Tag = 0x42324130; // 'B2A0'
+ public static final int icSigBToA1Tag = 0x42324131; // 'B2A1'
+ public static final int icSigBToA2Tag = 0x42324132; // 'B2A2'
+ public static final int icSigCalibrationDateTimeTag = 0x63616C74; // 'calt'
+ public static final int icSigCharTargetTag = 0x74617267; // 'targ'
+ public static final int icSigCopyrightTag = 0x63707274; // 'cprt'
+ public static final int icSigCrdInfoTag = 0x63726469; // 'crdi'
+ public static final int icSigDeviceMfgDescTag = 0x646D6E64; // 'dmnd'
+ public static final int icSigDeviceModelDescTag = 0x646D6464; // 'dmdd'
+ public static final int icSigDeviceSettingsTag = 0x64657673; // 'devs'
+ public static final int icSigGamutTag = 0x67616D74; // 'gamt'
+ public static final int icSigGrayTRCTag = 0x6b545243; // 'kTRC'
+ public static final int icSigGreenColorantTag = 0x6758595A; // 'gXYZ'
+ public static final int icSigGreenTRCTag = 0x67545243; // 'gTRC'
+ public static final int icSigLuminanceTag = 0x6C756d69; // 'lumi'
+ public static final int icSigMeasurementTag = 0x6D656173; // 'meas'
+ public static final int icSigMediaBlackPointTag = 0x626B7074; // 'bkpt'
+ public static final int icSigMediaWhitePointTag = 0x77747074; // 'wtpt'
+ public static final int icSigNamedColor2Tag = 0x6E636C32; // 'ncl2'
+ public static final int icSigOutputResponseTag = 0x72657370; // 'resp'
+ public static final int icSigPreview0Tag = 0x70726530; // 'pre0'
+ public static final int icSigPreview1Tag = 0x70726531; // 'pre1'
+ public static final int icSigPreview2Tag = 0x70726532; // 'pre2'
+ public static final int icSigProfileDescriptionTag = 0x64657363; // 'desc'
+ public static final int icSigProfileSequenceDescTag = 0x70736571; // 'pseq'
+ public static final int icSigPs2CRD0Tag = 0x70736430; // 'psd0'
+ public static final int icSigPs2CRD1Tag = 0x70736431; // 'psd1'
+ public static final int icSigPs2CRD2Tag = 0x70736432; // 'psd2'
+ public static final int icSigPs2CRD3Tag = 0x70736433; // 'psd3'
+ public static final int icSigPs2CSATag = 0x70733273; // 'ps2s'
+ public static final int icSigPs2RenderingIntentTag = 0x70733269; // 'ps2i'
+ public static final int icSigRedColorantTag = 0x7258595A; // 'rXYZ'
+ public static final int icSigRedTRCTag = 0x72545243; // 'rTRC'
+ public static final int icSigScreeningDescTag = 0x73637264; // 'scrd'
+ public static final int icSigScreeningTag = 0x7363726E; // 'scrn'
+ public static final int icSigTechnologyTag = 0x74656368; // 'tech'
+ public static final int icSigUcrBgTag = 0x62666420; // 'bfd '
+ public static final int icSigViewingCondDescTag = 0x76756564; // 'vued'
+ public static final int icSigViewingConditionsTag = 0x76696577; // 'view'
+ public static final int icSigChromaticityTag = 0x6368726D; // 'chrm'
+ /**
+ * Non-ICC tag 'head' for use in retrieving the header with getData()
+ */
+ public static final int icSigHead = 0x68656164;
+
+ /**
+ * Header offsets
+ */
public static final int icHdrSize = 0;
public static final int icHdrCmmId = 4;
public static final int icHdrVersion = 8;
@@ -171,129 +222,1025 @@ public class ICC_Profile implements Serializable
public static final int icHdrIlluminant = 68;
public static final int icHdrCreator = 80;
+ /**
+ *
+ */
public static final int icTagType = 0;
public static final int icTagReserved = 4;
public static final int icCurveCount = 8;
public static final int icCurveData = 12;
-
public static final int icXYZNumberX = 8;
/**
+ * offset of the Tag table
+ */
+ private static final int tagTableOffset = 128;
+
+ /**
* @serial
*/
- final int iccProfileSerializedDataVersion = 1;
+ private static final int iccProfileSerializedDataVersion = 1;
+
+ /**
+ * Constants related to generating profiles for
+ * built-in colorspace profiles
+ */
+ /**
+ * Copyright notice to stick into built-in-profile files.
+ */
+ private static final String copyrightNotice = "Generated by GNU Classpath.";
+
+ /**
+ * Resolution of the TRC to use for predefined profiles.
+ * 1024 should suffice.
+ */
+ private static final int TRC_POINTS = 1024;
+
+ /**
+ * CIE 1931 D50 white point (in Lab coordinates)
+ */
+ private static final float[] D50 = { 0.96422f, 1.00f, 0.82521f };
+
+ /**
+ * Color space profile ID
+ * Set to the predefined profile class (e.g. CS_sRGB) if a predefined
+ * color space is used, set to -1 otherwise.
+ * (or if the profile has been modified)
+ */
+ private transient int profileID;
+
+ /**
+ * The profile header data
+ */
+ private transient ProfileHeader header;
- transient int profileID;
+ /**
+ * A hashtable containing the profile tags as TagEntry objects
+ */
+ private transient Hashtable tagTable;
+ /**
+ * Contructor for predefined colorspaces
+ */
ICC_Profile(int profileID)
{
- this.profileID = profileID;
+ header = null;
+ tagTable = null;
+ createProfile(profileID);
+ }
+
+ /**
+ * Constructs an ICC_Profile from a header and a table of loaded tags.
+ */
+ ICC_Profile(ProfileHeader h, Hashtable tags) throws IllegalArgumentException
+ {
+ header = h;
+ tagTable = tags;
+ profileID = -1; // Not a predefined color space
+ }
+
+ /**
+ * Constructs an ICC_Profile from a byte array of data.
+ */
+ ICC_Profile(byte[] data) throws IllegalArgumentException
+ {
+ // get header and verify it
+ header = new ProfileHeader(data);
+ header.verifyHeader(data.length);
+ tagTable = createTagTable(data);
+ profileID = -1; // Not a predefined color space
}
+ /**
+ * Free up the used memory.
+ */
protected void finalize()
{
- // XXX What resources should we free?
+ header = null;
+ tagTable = null;
}
+ /**
+ * Returns an ICC_Profile instance from a byte array of profile data.
+ *
+ * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
+ * may be returned if appropriate.
+ *
+ * @throws IllegalArgumentException if the profile data is an invalid
+ * v2 profile.
+ *
+ * @param data - the profile data
+ * @return An ICC_Profile object
+ */
public static ICC_Profile getInstance(byte[] data)
{
- throw new Error("not implemented");
+ ProfileHeader header = new ProfileHeader(data);
+
+ // verify it as a correct ICC header, including size
+ header.verifyHeader(data.length);
+
+ Hashtable tags = createTagTable(data);
+
+ if (isRGBProfile(header, tags))
+ return new ICC_ProfileRGB(data);
+ if (isGrayProfile(header, tags))
+ return new ICC_ProfileGray(data);
+
+ return new ICC_Profile(header, tags);
}
+ /**
+ * Returns an predefined ICC_Profile instance.
+ *
+ * This will construct an ICC_Profile instance from one of the predefined
+ * color spaces in the ColorSpace class. (e.g. CS_sRGB, CS_GRAY, etc)
+ *
+ * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
+ * may be returned if appropriate.
+ *
+ * @return An ICC_Profile object
+ */
public static ICC_Profile getInstance(int cspace)
{
+ if (cspace == ColorSpace.CS_sRGB || cspace == ColorSpace.CS_LINEAR_RGB)
+ return new ICC_ProfileRGB(cspace);
+ if (cspace == ColorSpace.CS_GRAY)
+ return new ICC_ProfileGray(cspace);
return new ICC_Profile(cspace);
}
- public static ICC_Profile getInstance(String filename) throws IOException
+ /**
+ * Returns an ICC_Profile instance from an ICC Profile file.
+ *
+ * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
+ * may be returned if appropriate.
+ *
+ * @throws IllegalArgumentException if the profile data is an invalid
+ * v2 profile.
+ * @throws IOException if the file could not be read.
+ *
+ * @param filename - the file name of the profile file.
+ * @return An ICC_Profile object
+ */
+ public static ICC_Profile getInstance(String filename)
+ throws IOException
{
return getInstance(new FileInputStream(filename));
}
- public static ICC_Profile getInstance(InputStream in) throws IOException
+ /**
+ * Returns an ICC_Profile instance from an InputStream.
+ *
+ * This method can be used for reading ICC profiles embedded in files
+ * which support this. (JPEG and SVG for instance).
+ *
+ * The stream is treated in the following way: The profile header
+ * (128 bytes) is read first, and the header is validated. If the profile
+ * header is valid, it will then attempt to read the rest of the profile
+ * from the stream. The stream is not closed after reading.
+ *
+ * An instance of the specialized classes ICC_ProfileRGB or ICC_ProfileGray
+ * may be returned if appropriate.
+ *
+ * @throws IllegalArgumentException if the profile data is an invalid
+ * v2 profile.
+ * @throws IOException if the stream could not be read.
+ *
+ * @param in - the input stream to read the profile from.
+ * @return An ICC_Profile object
+ */
+ public static ICC_Profile getInstance(InputStream in)
+ throws IOException
{
- throw new Error("not implemented");
+ // read the header
+ byte[] headerData = new byte[ProfileHeader.HEADERSIZE];
+ if (in.read(headerData) != ProfileHeader.HEADERSIZE)
+ throw new IllegalArgumentException("Invalid profile header");
+
+ ProfileHeader header = new ProfileHeader(headerData);
+
+ // verify it as a correct ICC header, but do not verify the
+ // size as we are reading from a stream.
+ header.verifyHeader(-1);
+
+ // get the size
+ byte[] data = new byte[header.getSize()];
+ System.arraycopy(headerData, 0, data, 0, ProfileHeader.HEADERSIZE);
+
+ // read the rest
+ if (in.read(data, ProfileHeader.HEADERSIZE,
+ header.getSize() - ProfileHeader.HEADERSIZE) != header.getSize()
+ - ProfileHeader.HEADERSIZE)
+ throw new IOException("Incorrect profile size");
+
+ return getInstance(data);
}
+ /**
+ * Returns the major version number
+ */
public int getMajorVersion()
{
- throw new Error("not implemented");
+ return header.getMajorVersion();
}
+ /**
+ * Returns the minor version number.
+ *
+ * Only the least-significant byte contains data, in BCD form:
+ * the least-significant nibble is the BCD bug fix revision,
+ * the most-significant nibble is the BCD minor revision number.
+ *
+ * (E.g. For a v2.1.0 profile this will return <code>0x10</code>)
+ */
public int getMinorVersion()
{
- throw new Error("not implemented");
+ return header.getMinorVersion();
}
+ /**
+ * Returns the device class of this profile,
+ *
+ * (E.g. CLASS_INPUT for a scanner profile,
+ * CLASS_OUTPUT for a printer)
+ */
public int getProfileClass()
{
- throw new Error("not implemented");
+ return header.getProfileClass();
}
+ /**
+ * Returns the color space of this profile, in terms
+ * of the color space constants defined in ColorSpace.
+ * (For example, it may be a ColorSpace.TYPE_RGB)
+ */
public int getColorSpaceType()
{
- throw new Error("not implemented");
+ return header.getColorSpace();
}
+ /**
+ * Returns the color space of this profile's Profile Connection Space (OCS)
+ *
+ * In terms of the color space constants defined in ColorSpace.
+ * This may be TYPE_XYZ or TYPE_Lab
+ */
public int getPCSType()
{
- throw new Error("not implemented");
+ return header.getProfileColorSpace();
}
+ /**
+ * Writes the profile data to an ICC profile file.
+ * @param filename - The name of the file to write
+ * @throws IOException if the write failed.
+ */
public void write(String filename) throws IOException
{
- write(new FileOutputStream(filename));
+ FileOutputStream out = new FileOutputStream(filename);
+ write(out);
+ out.flush();
+ out.close();
}
+ /**
+ * Writes the profile data in ICC profile file-format to a stream.
+ * This is useful for embedding ICC profiles in file formats which
+ * support this (such as JPEG and SVG).
+ *
+ * The stream is not closed after writing.
+ * @param out - The outputstream to which the profile data should be written
+ * @throws IOException if the write failed.
+ */
public void write(OutputStream out) throws IOException
{
- throw new Error("not implemented");
+ out.write(getData());
}
+ /**
+ * Returns the data corresponding to this ICC_Profile as a byte array.
+ *
+ * @return The data in a byte array,
+ * where the first element corresponds to first byte of the profile file.
+ */
public byte[] getData()
{
- throw new Error("not implemented");
+ int size = getSize();
+ byte[] data = new byte[size];
+
+ // Header
+ System.arraycopy(header.getData(size), 0, data, 0, ProfileHeader.HEADERSIZE);
+ // # of tags
+ byte[] tt = getTagTable();
+ System.arraycopy(tt, 0, data, ProfileHeader.HEADERSIZE, tt.length);
+
+ Enumeration e = tagTable.elements();
+ while (e.hasMoreElements())
+ {
+ TagEntry tag = (TagEntry) e.nextElement();
+ System.arraycopy(tag.getData(), 0,
+ data, tag.getOffset(), tag.getSize());
+ }
+ return data;
}
+ /**
+ * Returns the ICC profile tag data
+ * The non ICC-tag icSigHead is also permitted to request the header data.
+ *
+ * @param tagSignature The ICC signature of the requested tag
+ * @return A byte array containing the tag data
+ */
public byte[] getData(int tagSignature)
{
- throw new Error("not implemented");
+ if (tagSignature == icSigHead)
+ return header.getData(getSize());
+
+ TagEntry t = (TagEntry) tagTable.get(TagEntry.tagHashKey(tagSignature));
+ if (t == null)
+ return null;
+ return t.getData();
}
+ /**
+ * Sets the ICC profile tag data.
+ *
+ * Note that an ICC profile can only contain one tag of each type, if
+ * a tag already exists with the given signature, it is replaced.
+ *
+ * @param tagSignature - The signature of the tag to set
+ * @param data - A byte array containing the tag data
+ */
public void setData(int tagSignature, byte[] data)
{
- throw new Error("not implemented");
+ profileID = -1; // Not a predefined color space if modified.
+
+ if (tagSignature == icSigHead)
+ header = new ProfileHeader(data);
+ else
+ {
+ TagEntry t = new TagEntry(tagSignature, data);
+ tagTable.put(t.hashKey(), t);
+ }
}
+ /**
+ * Get the number of components in the profile's device color space.
+ */
public int getNumComponents()
{
- switch (profileID)
+ int[] lookup =
+ {
+ ColorSpace.TYPE_RGB, 3, ColorSpace.TYPE_CMY, 3,
+ ColorSpace.TYPE_CMYK, 4, ColorSpace.TYPE_GRAY, 1,
+ ColorSpace.TYPE_YCbCr, 3, ColorSpace.TYPE_XYZ, 3,
+ ColorSpace.TYPE_Lab, 3, ColorSpace.TYPE_HSV, 3,
+ ColorSpace.TYPE_2CLR, 2, ColorSpace.TYPE_Luv, 3,
+ ColorSpace.TYPE_Yxy, 3, ColorSpace.TYPE_HLS, 3,
+ ColorSpace.TYPE_3CLR, 3, ColorSpace.TYPE_4CLR, 4,
+ ColorSpace.TYPE_5CLR, 5, ColorSpace.TYPE_6CLR, 6,
+ ColorSpace.TYPE_7CLR, 7, ColorSpace.TYPE_8CLR, 8,
+ ColorSpace.TYPE_9CLR, 9, ColorSpace.TYPE_ACLR, 10,
+ ColorSpace.TYPE_BCLR, 11, ColorSpace.TYPE_CCLR, 12,
+ ColorSpace.TYPE_DCLR, 13, ColorSpace.TYPE_ECLR, 14,
+ ColorSpace.TYPE_FCLR, 15
+ };
+ for (int i = 0; i < lookup.length; i += 2)
+ if (header.getColorSpace() == lookup[i])
+ return lookup[i + 1];
+ return 3; // should never happen.
+ }
+
+ /**
+ * After deserializing we must determine if the class we want
+ * is really one of the more specialized ICC_ProfileRGB or
+ * ICC_ProfileGray classes.
+ */
+ protected Object readResolve() throws ObjectStreamException
+ {
+ if (isRGBProfile(header, tagTable))
+ return new ICC_ProfileRGB(getData());
+ if (isGrayProfile(header, tagTable))
+ return new ICC_ProfileGray(getData());
+ return this;
+ }
+
+ /**
+ * Deserializes an instance
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ String predef = (String) s.readObject();
+ byte[] data = (byte[]) s.readObject();
+
+ if (data != null)
+ {
+ header = new ProfileHeader(data);
+ tagTable = createTagTable(data);
+ profileID = -1; // Not a predefined color space
+ }
+
+ if (predef != null)
+ {
+ predef = predef.intern();
+ if (predef.equals("CS_sRGB"))
+ createProfile(ColorSpace.CS_sRGB);
+ if (predef.equals("CS_LINEAR_RGB"))
+ createProfile(ColorSpace.CS_LINEAR_RGB);
+ if (predef.equals("CS_CIEXYZ"))
+ createProfile(ColorSpace.CS_CIEXYZ);
+ if (predef.equals("CS_GRAY"))
+ createProfile(ColorSpace.CS_GRAY);
+ if (predef.equals("CS_PYCC"))
+ createProfile(ColorSpace.CS_PYCC);
+ }
+ }
+
+ /**
+ * Serializes an instance
+ * The format is a String and a byte array,
+ * The string is non-null if the instance is one of the built-in profiles.
+ * Otherwise the byte array is non-null and represents the profile data.
+ */
+ private void writeObject(ObjectOutputStream s) throws IOException
+ {
+ s.defaultWriteObject();
+ if (profileID == ColorSpace.CS_sRGB)
+ s.writeObject("CS_sRGB");
+ else if (profileID == ColorSpace.CS_LINEAR_RGB)
+ s.writeObject("CS_LINEAR_RGB");
+ else if (profileID == ColorSpace.CS_CIEXYZ)
+ s.writeObject("CS_CIEXYZ");
+ else if (profileID == ColorSpace.CS_GRAY)
+ s.writeObject("CS_GRAY");
+ else if (profileID == ColorSpace.CS_PYCC)
+ s.writeObject("CS_PYCC");
+ else
+ {
+ s.writeObject(null); // null string
+ s.writeObject(getData()); // data
+ return;
+ }
+ s.writeObject(null); // null data
+ }
+
+ /**
+ * Sorts a ICC profile byte array into TagEntry objects stored in
+ * a hash table.
+ */
+ private static Hashtable createTagTable(byte[] data)
+ throws IllegalArgumentException
+ {
+ ByteBuffer buf = ByteBuffer.wrap(data);
+ int nTags = buf.getInt(tagTableOffset);
+
+ Hashtable tagTable = new Hashtable();
+ for (int i = 0; i < nTags; i++)
+ {
+ TagEntry te = new TagEntry(buf.getInt(tagTableOffset
+ + i * TagEntry.entrySize + 4),
+ buf.getInt(tagTableOffset
+ + i * TagEntry.entrySize + 8),
+ buf.getInt(tagTableOffset
+ + i * TagEntry.entrySize + 12),
+ data);
+
+ if (tagTable.put(te.hashKey(), te) != null)
+ throw new IllegalArgumentException("Duplicate tag in profile:" + te);
+ }
+ return tagTable;
+ }
+
+ /**
+ * Returns the total size of the padded, stored data
+ * Note: Tags must be stored on 4-byte aligned offsets.
+ */
+ private int getSize()
+ {
+ int totalSize = ProfileHeader.HEADERSIZE; // size of header
+
+ int tagTableSize = 4 + tagTable.size() * TagEntry.entrySize; // size of tag table
+ if ((tagTableSize & 0x0003) != 0)
+ tagTableSize += 4 - (tagTableSize & 0x0003); // pad
+ totalSize += tagTableSize;
+
+ Enumeration e = tagTable.elements();
+ while (e.hasMoreElements())
+ { // tag data
+ int tagSize = ((TagEntry) e.nextElement()).getSize();
+ if ((tagSize & 0x0003) != 0)
+ tagSize += 4 - (tagSize & 0x0003); // pad
+ totalSize += tagSize;
+ }
+ return totalSize;
+ }
+
+ /**
+ * Generates the tag index table
+ */
+ private byte[] getTagTable()
+ {
+ int tagTableSize = 4 + tagTable.size() * TagEntry.entrySize;
+ if ((tagTableSize & 0x0003) != 0)
+ tagTableSize += 4 - (tagTableSize & 0x0003); // pad
+
+ int offset = 4;
+ int tagOffset = ProfileHeader.HEADERSIZE + tagTableSize;
+ ByteBuffer buf = ByteBuffer.allocate(tagTableSize);
+ buf.putInt(tagTable.size()); // number of tags
+
+ Enumeration e = tagTable.elements();
+ while (e.hasMoreElements())
+ {
+ TagEntry tag = (TagEntry) e.nextElement();
+ buf.putInt(offset, tag.getSignature());
+ buf.putInt(offset + 4, tagOffset);
+ buf.putInt(offset + 8, tag.getSize());
+ tag.setOffset(tagOffset);
+ int tagSize = tag.getSize();
+ if ((tagSize & 0x0003) != 0)
+ tagSize += 4 - (tagSize & 0x0003); // pad
+ tagOffset += tagSize;
+ offset += 12;
+ }
+ return buf.array();
+ }
+
+ /**
+ * Returns if the criteria for an ICC_ProfileRGB are met.
+ * This means:
+ * Color space is TYPE_RGB
+ * (r,g,b)ColorantTags included
+ * (r,g,b)TRCTags included
+ * mediaWhitePointTag included
+ */
+ private static boolean isRGBProfile(ProfileHeader header, Hashtable tags)
+ {
+ if (header.getColorSpace() != ColorSpace.TYPE_RGB)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigRedColorantTag)) == null)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigGreenColorantTag)) == null)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigBlueColorantTag)) == null)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigRedTRCTag)) == null)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigGreenTRCTag)) == null)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigBlueTRCTag)) == null)
+ return false;
+ return (tags.get(TagEntry.tagHashKey(icSigMediaWhitePointTag)) != null);
+ }
+
+ /**
+ * Returns if the criteria for an ICC_ProfileGray are met.
+ * This means:
+ * Colorspace is TYPE_GRAY
+ * grayTRCTag included
+ * mediaWhitePointTag included
+ */
+ private static boolean isGrayProfile(ProfileHeader header, Hashtable tags)
+ {
+ if (header.getColorSpace() != ColorSpace.TYPE_GRAY)
+ return false;
+ if (tags.get(TagEntry.tagHashKey(icSigGrayTRCTag)) == null)
+ return false;
+ return (tags.get(TagEntry.tagHashKey(icSigMediaWhitePointTag)) != null);
+ }
+
+ /**
+ * Returns curve data for a 'curv'-type tag
+ * If it's a gamma curve, a single entry will be returned with the
+ * gamma value (including 1.0 for linear response)
+ * Otherwise the TRC table is returned.
+ *
+ * (Package private - used by ICC_ProfileRGB and ICC_ProfileGray)
+ */
+ short[] getCurve(int signature)
+ {
+ byte[] data = getData(signature);
+ short[] curve;
+
+ // can't find tag?
+ if (data == null)
+ return null;
+
+ // not an curve type tag?
+ ByteBuffer buf = ByteBuffer.wrap(data);
+ if (buf.getInt(0) != 0x63757276) // 'curv' type
+ return null;
+ int count = buf.getInt(8);
+ if (count == 0)
+ {
+ curve = new short[1];
+ curve[0] = 0x0100; // 1.00 in u8fixed8
+ return curve;
+ }
+ if (count == 1)
+ {
+ curve = new short[1];
+ curve[0] = buf.getShort(12); // other u8fixed8 gamma
+ return curve;
+ }
+ curve = new short[count];
+ for (int i = 0; i < count; i++)
+ curve[i] = buf.getShort(12 + i * 2);
+ return curve;
+ }
+
+ /**
+ * Returns XYZ tristimulus values for an 'XYZ ' type tag
+ * @return the XYZ values, or null if the tag was not an 'XYZ ' type tag.
+ *
+ * (Package private - used by ICC_ProfileXYZ and ICC_ProfileGray)
+ */
+ float[] getXYZData(int signature)
+ {
+ byte[] data = getData(signature);
+
+ // can't find tag?
+ if (data == null)
+ return null;
+
+ // not an XYZData type tag?
+ ByteBuffer buf = ByteBuffer.wrap(data);
+ if (buf.getInt(0) != icSigXYZData) // 'XYZ ' type
+ return null;
+
+ float[] point = new float[3];
+
+ // get the X,Y,Z tristimulus values
+ point[0] = ((float) buf.getInt(8)) / 65536f;
+ point[1] = ((float) buf.getInt(12)) / 65536f;
+ point[2] = ((float) buf.getInt(16)) / 65536f;
+ return point;
+ }
+
+ /**
+ * Returns the profile ID if it's a predefined profile
+ * Or -1 for a profile loaded from an ICC profile
+ *
+ * (Package private - used by ICC_ColorSpace)
+ */
+ int isPredefined()
+ {
+ return profileID;
+ }
+
+ /**
+ * Creates a tag of XYZ-value type.
+ */
+ private byte[] makeXYZData(float[] values)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(20);
+ buf.putInt(0, icSigXYZData); // 'XYZ '
+ buf.putInt(4, 0);
+ buf.putInt(8, (int) (values[0] * 65536.0));
+ buf.putInt(12, (int) (values[1] * 65536.0));
+ buf.putInt(16, (int) (values[2] * 65536.0));
+ return buf.array();
+ }
+
+ /**
+ * Creates a tag of text type
+ */
+ private byte[] makeTextTag(String text)
+ {
+ int length = text.length();
+ ByteBuffer buf = ByteBuffer.allocate(8 + length + 1);
+ byte[] data;
+ try
+ {
+ data = text.getBytes("US-ASCII");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ data = new byte[length]; // shouldn't happen
+ }
+
+ buf.putInt(0, (int) 0x74657874); // 'text'
+ buf.putInt(4, 0);
+ for (int i = 0; i < length; i++)
+ buf.put(8 + i, data[i]);
+ buf.put(8 + length, (byte) 0); // null-terminate
+ return buf.array();
+ }
+
+ /**
+ * Creates a tag of textDescriptionType
+ */
+ private byte[] makeDescTag(String text)
+ {
+ int length = text.length();
+ ByteBuffer buf = ByteBuffer.allocate(90 + length + 1);
+ buf.putInt(0, (int) 0x64657363); // 'desc'
+ buf.putInt(4, 0); // reserved
+ buf.putInt(8, length + 1); // ASCII length, including null termination
+ byte[] data;
+
+ try
+ {
+ data = text.getBytes("US-ASCII");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ data = new byte[length]; // shouldn't happen
+ }
+
+ for (int i = 0; i < length; i++)
+ buf.put(12 + i, data[i]);
+ buf.put(12 + length, (byte) 0); // null-terminate
+
+ for (int i = 0; i < 39; i++)
+ buf.putShort(13 + length + (i * 2), (short) 0); // 78 bytes we can ignore
+
+ return buf.array();
+ }
+
+ /**
+ * Creates a tag of TRC type (linear curve)
+ */
+ private byte[] makeTRC()
+ {
+ ByteBuffer buf = ByteBuffer.allocate(12);
+ buf.putInt(0, 0x63757276); // 'curv' type
+ buf.putInt(4, 0); // reserved
+ buf.putInt(8, 0);
+ return buf.array();
+ }
+
+ /**
+ * Creates a tag of TRC type (single gamma value)
+ */
+ private byte[] makeTRC(float gamma)
+ {
+ short gammaValue = (short) (gamma * 256f);
+ ByteBuffer buf = ByteBuffer.allocate(14);
+ buf.putInt(0, 0x63757276); // 'curv' type
+ buf.putInt(4, 0); // reserved
+ buf.putInt(8, 1);
+ buf.putShort(12, gammaValue); // 1.00 in u8fixed8
+ return buf.array();
+ }
+
+ /**
+ * Creates a tag of TRC type (TRC curve points)
+ */
+ private byte[] makeTRC(float[] trc)
+ {
+ ByteBuffer buf = ByteBuffer.allocate(12 + 2 * trc.length);
+ buf.putInt(0, 0x63757276); // 'curv' type
+ buf.putInt(4, 0); // reserved
+ buf.putInt(8, trc.length); // number of points
+
+ // put the curve values
+ for (int i = 0; i < trc.length; i++)
+ buf.putShort(12 + i * 2, (short) (trc[i] * 65535f));
+
+ return buf.array();
+ }
+
+ /**
+ * Creates an identity color lookup table.
+ */
+ private byte[] makeIdentityClut()
+ {
+ final int nIn = 3;
+ final int nOut = 3;
+ final int nInEntries = 256;
+ final int nOutEntries = 256;
+ final int gridpoints = 16;
+
+ // gridpoints**nIn
+ final int clutSize = 2 * nOut * gridpoints * gridpoints * gridpoints;
+ final int totalSize = clutSize + 2 * nInEntries * nIn
+ + 2 * nOutEntries * nOut + 52;
+
+ ByteBuffer buf = ByteBuffer.allocate(totalSize);
+ buf.putInt(0, 0x6D667432); // 'mft2'
+ buf.putInt(4, 0); // reserved
+ buf.put(8, (byte) nIn); // number input channels
+ buf.put(9, (byte) nOut); // number output channels
+ buf.put(10, (byte) gridpoints); // number gridpoints
+ buf.put(11, (byte) 0); // padding
+
+ // identity matrix
+ buf.putInt(12, 65536); // = 1 in s15.16 fixed point
+ buf.putInt(16, 0);
+ buf.putInt(20, 0);
+ buf.putInt(24, 0);
+ buf.putInt(28, 65536);
+ buf.putInt(32, 0);
+ buf.putInt(36, 0);
+ buf.putInt(40, 0);
+ buf.putInt(44, 65536);
+
+ buf.putShort(48, (short) nInEntries); // input table entries
+ buf.putShort(50, (short) nOutEntries); // output table entries
+
+ // write the linear input channels, unsigned 16.16 fixed point,
+ // from 0.0 to FF.FF
+ for (int channel = 0; channel < 3; channel++)
+ for (int i = 0; i < nInEntries; i++)
+ {
+ short n = (short) ((i << 8) | i); // assumes 256 entries
+ buf.putShort(52 + (channel * nInEntries + i) * 2, n);
+ }
+ int clutOffset = 52 + nInEntries * nIn * 2;
+
+ for (int x = 0; x < gridpoints; x++)
+ for (int y = 0; y < gridpoints; y++)
+ for (int z = 0; z < gridpoints; z++)
+ {
+ int offset = clutOffset + z * 2 * nOut + y * gridpoints * 2 * nOut
+ + x * gridpoints * gridpoints * 2 * nOut;
+ double xf = ((double) x) / ((double) gridpoints - 1.0);
+ double yf = ((double) y) / ((double) gridpoints - 1.0);
+ double zf = ((double) z) / ((double) gridpoints - 1.0);
+ buf.putShort(offset, (short) (xf * 65535.0));
+ buf.putShort(offset + 2, (short) (yf * 65535.0));
+ buf.putShort(offset + 4, (short) (zf * 65535.0));
+ }
+
+ for (int channel = 0; channel < 3; channel++)
+ for (int i = 0; i < nOutEntries; i++)
+ {
+ short n = (short) ((i << 8) | i); // assumes 256 entries
+ buf.putShort(clutOffset + clutSize + (channel * nOutEntries + i) * 2,
+ n);
+ }
+
+ return buf.array();
+ }
+
+ /**
+ * Creates profile data corresponding to the built-in colorspaces.
+ */
+ private void createProfile(int colorSpace) throws IllegalArgumentException
+ {
+ this.profileID = colorSpace;
+ header = new ProfileHeader();
+ tagTable = new Hashtable();
+
+ switch (colorSpace)
{
case ColorSpace.CS_sRGB:
+ createRGBProfile();
+ return;
case ColorSpace.CS_LINEAR_RGB:
+ createLinearRGBProfile();
+ return;
case ColorSpace.CS_CIEXYZ:
- return 3;
+ createCIEProfile();
+ return;
case ColorSpace.CS_GRAY:
- return 1;
- case ColorSpace.CS_PYCC: // have no clue about this one
+ createGrayProfile();
+ return;
+ case ColorSpace.CS_PYCC:
+ createPyccProfile();
+ return;
default:
- throw new UnsupportedOperationException("profile not implemented");
+ throw new IllegalArgumentException("Not a predefined color space!");
}
}
- protected Object readResolve() throws ObjectStreamException
+ /**
+ * Creates an ICC_Profile representing the sRGB color space
+ */
+ private void createRGBProfile()
{
- throw new Error("not implemented");
+ header.setColorSpace( ColorSpace.TYPE_RGB );
+ header.setProfileColorSpace( ColorSpace.TYPE_XYZ );
+ ICC_ColorSpace cs = new ICC_ColorSpace(this);
+
+ float[] r = { 1f, 0f, 0f };
+ float[] g = { 0f, 1f, 0f };
+ float[] b = { 0f, 0f, 1f };
+ float[] black = { 0f, 0f, 0f };
+
+ // CIE 1931 D50 white point (in Lab coordinates)
+ float[] white = D50;
+
+ // Get tristimulus values (matrix elements)
+ r = cs.toCIEXYZ(r);
+ g = cs.toCIEXYZ(g);
+ b = cs.toCIEXYZ(b);
+
+ // Generate the sRGB TRC curve, this is the linear->nonlinear
+ // RGB transform.
+ cs = new ICC_ColorSpace(getInstance(ICC_ColorSpace.CS_LINEAR_RGB));
+ float[] points = new float[TRC_POINTS];
+ float[] in = new float[3];
+ for (int i = 0; i < TRC_POINTS; i++)
+ {
+ in[0] = in[1] = in[2] = ((float) i) / ((float) TRC_POINTS - 1);
+ in = cs.fromRGB(in);
+ // Note this value is the same for all components.
+ points[i] = in[0];
+ }
+
+ setData(icSigRedColorantTag, makeXYZData(r));
+ setData(icSigGreenColorantTag, makeXYZData(g));
+ setData(icSigBlueColorantTag, makeXYZData(b));
+ setData(icSigMediaWhitePointTag, makeXYZData(white));
+ setData(icSigMediaBlackPointTag, makeXYZData(black));
+ setData(icSigRedTRCTag, makeTRC(points));
+ setData(icSigGreenTRCTag, makeTRC(points));
+ setData(icSigBlueTRCTag, makeTRC(points));
+ setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
+ setData(icSigProfileDescriptionTag, makeDescTag("Generic sRGB"));
+ this.profileID = ColorSpace.CS_sRGB;
}
- private void readObject(ObjectInputStream s)
- throws IOException, ClassNotFoundException
+ /**
+ * Creates an linear sRGB profile
+ */
+ private void createLinearRGBProfile()
{
- throw new Error("not implemented");
+ header.setColorSpace(ColorSpace.TYPE_RGB);
+ header.setProfileColorSpace(ColorSpace.TYPE_XYZ);
+ ICC_ColorSpace cs = new ICC_ColorSpace(this);
+
+ float[] r = { 1f, 0f, 0f };
+ float[] g = { 0f, 1f, 0f };
+ float[] b = { 0f, 0f, 1f };
+ float[] black = { 0f, 0f, 0f };
+
+ float[] white = D50;
+
+ // Get tristimulus values (matrix elements)
+ r = cs.toCIEXYZ(r);
+ g = cs.toCIEXYZ(g);
+ b = cs.toCIEXYZ(b);
+
+ setData(icSigRedColorantTag, makeXYZData(r));
+ setData(icSigGreenColorantTag, makeXYZData(g));
+ setData(icSigBlueColorantTag, makeXYZData(b));
+
+ setData(icSigMediaWhitePointTag, makeXYZData(white));
+ setData(icSigMediaBlackPointTag, makeXYZData(black));
+
+ setData(icSigRedTRCTag, makeTRC());
+ setData(icSigGreenTRCTag, makeTRC());
+ setData(icSigBlueTRCTag, makeTRC());
+ setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
+ setData(icSigProfileDescriptionTag, makeDescTag("Linear RGB"));
+ this.profileID = ColorSpace.CS_LINEAR_RGB;
}
- private void writeObject(ObjectOutputStream s) throws IOException
+ /**
+ * Creates an CIE XYZ identity profile
+ */
+ private void createCIEProfile()
+ {
+ header.setColorSpace( ColorSpace.TYPE_XYZ );
+ header.setProfileColorSpace( ColorSpace.TYPE_XYZ );
+ header.setProfileClass( CLASS_COLORSPACECONVERSION );
+ ICC_ColorSpace cs = new ICC_ColorSpace(this);
+
+ float[] white = D50;
+
+ setData(icSigMediaWhitePointTag, makeXYZData(white));
+ setData(icSigAToB0Tag, makeIdentityClut());
+ setData(icSigBToA0Tag, makeIdentityClut());
+ setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
+ setData(icSigProfileDescriptionTag, makeDescTag("CIE XYZ identity profile"));
+ this.profileID = ColorSpace.CS_CIEXYZ;
+ }
+
+ /**
+ * Creates a linear gray ICC_Profile
+ */
+ private void createGrayProfile()
{
- throw new Error("not implemented");
+ header.setColorSpace(ColorSpace.TYPE_GRAY);
+ header.setProfileColorSpace(ColorSpace.TYPE_XYZ);
+
+ // CIE 1931 D50 white point (in Lab coordinates)
+ float[] white = D50;
+
+ setData(icSigMediaWhitePointTag, makeXYZData(white));
+ setData(icSigGrayTRCTag, makeTRC(1.0f));
+ setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
+ setData(icSigProfileDescriptionTag, makeDescTag("Linear grayscale"));
+ this.profileID = ColorSpace.CS_GRAY;
+ }
+
+ /**
+ * XXX Implement me
+ */
+ private void createPyccProfile()
+ {
+ header.setColorSpace(ColorSpace.TYPE_3CLR);
+ header.setProfileColorSpace(ColorSpace.TYPE_XYZ);
+
+ // Create CLUTs here. :-)
+
+ setData(icSigCopyrightTag, makeTextTag(copyrightNotice));
+ setData(icSigProfileDescriptionTag, makeDescTag("Photo YCC"));
+ this.profileID = ColorSpace.CS_PYCC;
}
} // class ICC_Profile
diff --git a/libjava/java/awt/color/ICC_ProfileGray.java b/libjava/java/awt/color/ICC_ProfileGray.java
index 6aed7eefe0f..54c2771332d 100644
--- a/libjava/java/awt/color/ICC_ProfileGray.java
+++ b/libjava/java/awt/color/ICC_ProfileGray.java
@@ -1,5 +1,5 @@
/* ICC_ProfileGray.java -- the ICC profile for a Gray colorspace
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,7 +39,22 @@ exception statement from your version. */
package java.awt.color;
/**
- * STUBBED
+ * ICC_ProfileGray - a special case of ICC_Profiles.
+ *
+ * The ICC_Profile.getInstance() method will return an instance of the
+ * ICC_ProfileGray subclass when all the following conditions are met:
+ * The device color space of the profile is TYPE_GRAY.
+ * The profile contains a gray TRCTag.
+ * The profile contains a mediaWhitePointTag.
+ *
+ * As per the ICC specification, the color space conversion can then
+ * be done through the following method:
+ * linearGray = grayTRC[deviceGray]
+ *
+ * Note that if the profile contains a CLUT for the color space conversion,
+ * it should be used instead, and the TRC information ignored.
+ *
+ * @author Sven de Marothy
* @since 1.2
*/
public class ICC_ProfileGray extends ICC_Profile
@@ -48,24 +63,71 @@ public class ICC_ProfileGray extends ICC_Profile
* Compatible with JDK 1.2+.
*/
private static final long serialVersionUID = -1124721290732002649L;
+ private transient float[] whitePoint;
- ICC_ProfileGray()
+ /**
+ * Package-private constructor used by ICC_ColorSpace for creating an
+ * ICC_ProfileGray from a predefined ColorSpace (CS_GRAY)
+ */
+ ICC_ProfileGray(int cspace)
+ {
+ super(cspace);
+ whitePoint = getXYZData(icSigMediaWhitePointTag);
+ }
+
+ /**
+ * Package-private constructor used by ICC_ColorSpace for creating an
+ * ICC_ProfileGray from profile data.
+ */
+ ICC_ProfileGray(byte[] data)
{
- super(ColorSpace.CS_GRAY);
+ super(data);
+ whitePoint = getXYZData(icSigMediaWhitePointTag);
}
+
+ /**
+ * Returns the media white point of the profile.
+ */
public float[] getMediaWhitePoint()
{
- return null;
+ float[] wp = new float[3];
+ wp[0] = whitePoint[0];
+ wp[1] = whitePoint[1];
+ wp[2] = whitePoint[2];
+ return wp;
}
+ /**
+ * Returns the TRC gamma value.
+ * @throws ProfileDataException if the TRC is described by a lookup
+ * table and not a gamma value.
+ */
public float getGamma()
{
- return 0;
+ short[] data = getCurve(icSigGrayTRCTag);
+ if (data == null)
+ throw new IllegalArgumentException("Couldn't read Gray TRC data.");
+ if (data.length != 1)
+ throw new ProfileDataException("TRC is a table, not a gamma value.");
+
+ // convert the unsigned 7.8 fixed-point gamma to a float.
+ double gamma = (double) (data[0] & (0xFFFF)) / 256.0;
+ return (float) gamma;
}
+ /**
+ * Returns the TRC lookup table.
+ * @throws ProfileDataException if the TRC is described by a gamma value
+ * and not a lookup table.
+ */
public short[] getTRC()
{
- return null;
+ short[] data = getCurve(icSigGrayTRCTag);
+ if (data == null)
+ throw new IllegalArgumentException("Couldn't read Gray TRC data.");
+ if (data.length <= 1)
+ throw new ProfileDataException("Gamma value, not a TRC table.");
+ return data;
}
} // class ICC_ProfileGray
diff --git a/libjava/java/awt/color/ICC_ProfileRGB.java b/libjava/java/awt/color/ICC_ProfileRGB.java
index aab7578b22e..cb947f67705 100644
--- a/libjava/java/awt/color/ICC_ProfileRGB.java
+++ b/libjava/java/awt/color/ICC_ProfileRGB.java
@@ -1,5 +1,5 @@
/* ICC_ProfileRGB.java -- the ICC profile for a RGB colorspace
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,7 +39,34 @@ exception statement from your version. */
package java.awt.color;
/**
- * STUBBED
+ * ICC_ProfileRGB - a special case of ICC_Profiles.
+ *
+ * The ICC_Profile.getInstance() method will return an instance of the
+ * ICC_ProfileRGB subclass when all the following conditions are met:
+ * The device color space of the profile is TYPE_RGB.
+ * The profile contains red, green and blue ColorantTags.
+ * The profile contains red, green and blue TRCTags.
+ * The profile contains a mediaWhitePointTag included.
+ *
+ * As per the ICC specification, the color space conversion can then
+ * be done through the following method:
+ * linearR = redTRC[deviceR]
+ * linearG = greenTRC[deviceG]
+ * linearB = blueTRC[deviceB]
+ * TRC curves are either a single gamma value, or a 1-dimensional lookup table.
+ *
+ * Followed by the matrix transform:
+ * PCS = M*linear
+ *
+ * Where PCS is the vector of profile color space (must be XYZ) coordinates,
+ * linear is the vector of linear RGB coordinates, and the matrix M is
+ * constructed from the ColorantTags, where the columns are red, green and
+ * blue respectively, and the rows are X, Y and Z.
+ *
+ * Note that if the profile contains a CLUT for the color space conversion,
+ * it should be used instead, and the TRC information ignored.
+ *
+ * @author Sven de Marothy
* @since 1.2
*/
public class ICC_ProfileRGB extends ICC_Profile
@@ -50,31 +77,151 @@ public class ICC_ProfileRGB extends ICC_Profile
private static final long serialVersionUID = 8505067385152579334L;
public static final int REDCOMPONENT = 0;
+
public static final int GREENCOMPONENT = 1;
+
public static final int BLUECOMPONENT = 2;
- ICC_ProfileRGB()
+ private transient float[][] matrix;
+
+ private transient float[] gamma;
+
+ private transient float[] whitePoint;
+
+
+ /**
+ * Package-private constructor used by ICC_ColorSpace for creating an
+ * ICC_ProfileRGB from a predefined ColorSpace (CS_LINEAR_RGB and CS_sRGB)
+ */
+ ICC_ProfileRGB(int cspace)
{
- super(ColorSpace.CS_sRGB);
+ super(cspace);
+ matrix = createMatrix();
+ whitePoint = getXYZData(icSigMediaWhitePointTag);
}
+ /**
+ * Package-private constructor used by ICC_ColorSpace for creating an
+ * ICC_ProfileRGB from profile data.
+ */
+ ICC_ProfileRGB(byte[] data)
+ {
+ super(data);
+ matrix = createMatrix();
+ whitePoint = getXYZData(icSigMediaWhitePointTag);
+ }
+
+ /**
+ * Returns the media white point of the profile.
+ */
public float[] getMediaWhitePoint()
{
- return null;
+ float[] wp = new float[3];
+ wp[0] = whitePoint[0];
+ wp[1] = whitePoint[1];
+ wp[2] = whitePoint[2];
+ return wp;
}
+ /**
+ * Returns the colorant matrix of the conversion.
+ */
public float[][] getMatrix()
{
- return null;
+ float[][] mat = new float[3][3];
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ mat[i][j] = matrix[i][j];
+ return mat;
}
+ /**
+ * Returns the gamma value of a component
+ * @throws ProfileDataException if the TRC is described by a lookup
+ * table and not a gamma value.
+ */
public float getGamma(int component)
{
- return 0;
+ short[] data;
+ switch (component)
+ {
+ case REDCOMPONENT:
+ data = getCurve(icSigRedTRCTag);
+ break;
+ case GREENCOMPONENT:
+ data = getCurve(icSigGreenTRCTag);
+ break;
+ case BLUECOMPONENT:
+ data = getCurve(icSigBlueTRCTag);
+ break;
+ default:
+ throw new IllegalArgumentException("Not a valid component");
+ }
+ if (data == null)
+ throw new IllegalArgumentException("Error reading TRC");
+
+ if (data.length != 1)
+ throw new ProfileDataException("Not a single-gamma TRC");
+
+ // convert the unsigned 7.8 fixed-point gamma to a float.
+ float gamma = (float) (((int) data[0] & 0xFF00) >> 8);
+ double fraction = ((int) data[0] & 0x00FF) / 256.0;
+ gamma += (float) fraction;
+ return gamma;
}
+ /**
+ * Returns the TRC lookup table for a component
+ * @throws ProfileDataException if the TRC is described by a gamma
+ * value and not a lookup table.
+ */
public short[] getTRC(int component)
{
- return null;
+ short[] data;
+ switch (component)
+ {
+ case REDCOMPONENT:
+ data = getCurve(icSigRedTRCTag);
+ break;
+ case GREENCOMPONENT:
+ data = getCurve(icSigGreenTRCTag);
+ break;
+ case BLUECOMPONENT:
+ data = getCurve(icSigBlueTRCTag);
+ break;
+ default:
+ throw new IllegalArgumentException("Not a valid component");
+ }
+ if (data == null)
+ throw new IllegalArgumentException("Error reading TRC");
+
+ if (data.length <= 1)
+ throw new ProfileDataException("Gamma value, not a TRC table.");
+
+ return data;
+ }
+
+ /**
+ * Creates the colorspace conversion matrix from the RGB tristimulus
+ * values.
+ */
+ private float[][] createMatrix() throws IllegalArgumentException
+ {
+ float[][] mat = new float[3][3];
+ float[] r;
+ float[] g;
+ float[] b;
+ r = getXYZData(icSigRedColorantTag);
+ g = getXYZData(icSigGreenColorantTag);
+ b = getXYZData(icSigBlueColorantTag);
+ if (r == null || g == null || b == null)
+ throw new IllegalArgumentException("Error reading colorant tags!");
+ for (int i = 0; i < 3; i++)
+ {
+ mat[i][0] = r[i];
+ mat[i][1] = g[i];
+ mat[i][2] = b[i];
+ }
+ return mat;
}
} // class ICC_ProfileRGB
diff --git a/libjava/java/awt/datatransfer/Clipboard.java b/libjava/java/awt/datatransfer/Clipboard.java
index 93bba7c1a3d..ca9b6ebdb0a 100644
--- a/libjava/java/awt/datatransfer/Clipboard.java
+++ b/libjava/java/awt/datatransfer/Clipboard.java
@@ -39,102 +39,76 @@ exception statement from your version. */
package java.awt.datatransfer;
/**
- * This class allows data to be transferred using a cut and paste type
- * mechanism.
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- */
-public class Clipboard
-{
-
-/*
- * Instance Variables
- */
-
-/**
- * The data being transferred.
- */
-protected Transferable contents;
-
-/**
- * The owner of this clipboard.
- */
-protected ClipboardOwner owner;
-
-// The clipboard name
-private String name;
-
-/*************************************************************************/
-
-/*
- * Constructors
- */
-
-/**
- * Initializes a new instance of <code>Clipboard</code> with the
- * specified name.
- *
- * @param name The clipboard name.
- */
-public
-Clipboard(String name)
-{
- this.name = name;
-}
-
-/*************************************************************************/
-
-/*
- * Instance Methods
+ * This class allows data to be transferred using a cut and paste type
+ * mechanism.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
*/
-
-/**
- * Returns the name of the clipboard.
- */
-public String
-getName()
-{
- return(name);
-}
-
-/*************************************************************************/
-
-/**
- * Returns the contents of the clipboard.
- *
- * @param requestor The object requesting the contents.
- *
- * @exception IllegalStateException If the clipboard is currently unavailable
- */
-public synchronized Transferable
-getContents(Object requestor)
-{
- return(contents);
-}
-
-/*************************************************************************/
-
-/**
- * Sets the content and owner of this clipboard.
- * If the given owner is different from the current owner
- * then lostOwnership is called on the current owner.
- * XXX - is this called with the old or new contents.
- *
- * @param contents The new clipboard contents.
- * @param owner The new clipboard owner
- *
- * @exception IllegalStateException If the clipboard is currently unavailable
- */
-public synchronized void
-setContents(Transferable contents, ClipboardOwner owner)
+public class Clipboard
{
- if (this.owner != owner)
- if (this.owner != null)
- this.owner.lostOwnership(this, contents);
+ /**
+ * The data being transferred.
+ */
+ protected Transferable contents;
+
+ /**
+ * The owner of this clipboard.
+ */
+ protected ClipboardOwner owner;
+
+ // The clipboard name
+ private String name;
+
+ /**
+ * Initializes a new instance of <code>Clipboard</code> with the
+ * specified name.
+ *
+ * @param name The clipboard name.
+ */
+ public Clipboard(String name)
+ {
+ this.name = name;
+ }
+
+ /**
+ * Returns the name of the clipboard.
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Returns the contents of the clipboard.
+ *
+ * @param requestor The object requesting the contents.
+ *
+ * @exception IllegalStateException If the clipboard is currently unavailable
+ */
+ public synchronized Transferable getContents(Object requestor)
+ {
+ return contents;
+ }
+
+ /**
+ * Sets the content and owner of this clipboard.
+ * If the given owner is different from the current owner
+ * then lostOwnership is called on the current owner.
+ * XXX - is this called with the old or new contents.
+ *
+ * @param contents The new clipboard contents.
+ * @param owner The new clipboard owner
+ *
+ * @exception IllegalStateException If the clipboard is currently unavailable
+ */
+ public synchronized void setContents(Transferable contents, ClipboardOwner owner)
+ {
+ if (this.owner != owner)
+ if (this.owner != null)
+ this.owner.lostOwnership(this, contents);
- this.owner = owner;
- this.contents = contents;
+ this.owner = owner;
+ this.contents = contents;
+ }
}
-} // class Clipboard
-
diff --git a/libjava/java/awt/datatransfer/ClipboardOwner.java b/libjava/java/awt/datatransfer/ClipboardOwner.java
index 28e58aae184..b5ca9e37d8f 100644
--- a/libjava/java/awt/datatransfer/ClipboardOwner.java
+++ b/libjava/java/awt/datatransfer/ClipboardOwner.java
@@ -53,6 +53,5 @@ public interface ClipboardOwner
* @param contents The contents of the clipboard which are no longer owned.
*/
void lostOwnership (Clipboard clipboard, Transferable contents);
-
-} // interface ClipboardOwner
+}
diff --git a/libjava/java/awt/datatransfer/DataFlavor.java b/libjava/java/awt/datatransfer/DataFlavor.java
index 3ec21911929..19f69d5c726 100644
--- a/libjava/java/awt/datatransfer/DataFlavor.java
+++ b/libjava/java/awt/datatransfer/DataFlavor.java
@@ -39,11 +39,11 @@ exception statement from your version. */
package java.awt.datatransfer;
import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.IOException;
-import java.io.ObjectOutput;
import java.io.ObjectInput;
+import java.io.ObjectOutput;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
@@ -328,7 +328,6 @@ getRepresentationClassFromMime(String mimeString, ClassLoader classLoader)
*
* @param mimeType The MIME type for this flavor.
* @param humanPresentableName The display name of this flavor.
- * @param classLoader The class loader for finding classes.
*
* @exception IllegalArgumentException If the representation class
* specified cannot be loaded.
@@ -529,7 +528,7 @@ isMimeTypeEqual(String mimeType)
* @return <code>true</code> if the flavor's MIME type is equal to this
* object's MIME type, <code>false</code> otherwise.
*/
-public boolean
+public final boolean
isMimeTypeEqual(DataFlavor flavor)
{
return(isMimeTypeEqual(flavor.getMimeType()));
@@ -555,7 +554,7 @@ isMimeTypeSerializedObject()
* Tests whether or not this flavor has a representation class of
* <code>java.io.InputStream</code>.
*
- * @param <code>true</code> if the representation class of this flavor
+ * @return <code>true</code> if the representation class of this flavor
* is <code>java.io.InputStream</code>, <code>false</code> otherwise.
*/
public boolean
@@ -570,7 +569,7 @@ isRepresentationClassInputStream()
* Tests whether the representation class for this flavor is
* serializable.
*
- * @param <code>true</code> if the representation class is serializable,
+ * @return <code>true</code> if the representation class is serializable,
* <code>false</code> otherwise.
*/
public boolean
diff --git a/libjava/java/awt/datatransfer/FlavorTable.java b/libjava/java/awt/datatransfer/FlavorTable.java
index 23fa9fa1fc1..3822cdec60b 100644
--- a/libjava/java/awt/datatransfer/FlavorTable.java
+++ b/libjava/java/awt/datatransfer/FlavorTable.java
@@ -66,8 +66,8 @@ public interface FlavorTable extends FlavorMap
* list should be sorted from best to worst. The list must be modifiable
* without affecting this table.
*
- * @param native the native to look up, or null to return all flavors
+ * @param name the native name to look up, or null to return all flavors
* @return the sorted list of flavors
*/
List getFlavorsForNative(String name);
-} // interface FlavorTable
+}
diff --git a/libjava/java/awt/datatransfer/StringSelection.java b/libjava/java/awt/datatransfer/StringSelection.java
index 51addb7296c..b41c936990d 100644
--- a/libjava/java/awt/datatransfer/StringSelection.java
+++ b/libjava/java/awt/datatransfer/StringSelection.java
@@ -1,5 +1,5 @@
/* StringSelection.java -- Clipboard handler for text.
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,8 @@ exception statement from your version. */
package java.awt.datatransfer;
-import java.io.StringReader;
import java.io.IOException;
+import java.io.StringReader;
/**
* This class transfers a string as plain text using the clipboard.
@@ -68,26 +68,15 @@ static final DataFlavor[] supported_flavors
// This is the data to transfer
private String data;
-/*************************************************************************/
-
-/*
- * Constructors
- */
-
-/**
- * Transfer the specfied string as text.
- */
-public
-StringSelection(String data)
-{
- this.data = data;
-}
-
-/*************************************************************************/
-
-/*
- * Instance Methods
- */
+ /**
+ * Transfer the specfied string as text.
+ *
+ * @param data the data for the string selection
+ */
+ public StringSelection(String data)
+ {
+ this.data = data;
+ }
/**
* Returns a list of supported data flavors.
diff --git a/libjava/java/awt/datatransfer/SystemFlavorMap.java b/libjava/java/awt/datatransfer/SystemFlavorMap.java
index 7d914120e8f..826992b7c7c 100644
--- a/libjava/java/awt/datatransfer/SystemFlavorMap.java
+++ b/libjava/java/awt/datatransfer/SystemFlavorMap.java
@@ -1,5 +1,5 @@
/* SystemFlavorMap.java -- Maps between native flavor names and MIME types.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -39,8 +39,8 @@ exception statement from your version. */
package java.awt.datatransfer;
import java.util.HashMap;
-import java.util.Map;
import java.util.List;
+import java.util.Map;
/**
* This class maps between native platform type names and DataFlavors.
diff --git a/libjava/java/awt/dnd/Autoscroll.java b/libjava/java/awt/dnd/Autoscroll.java
index 5c5233874cb..ae868c077b3 100644
--- a/libjava/java/awt/dnd/Autoscroll.java
+++ b/libjava/java/awt/dnd/Autoscroll.java
@@ -1,5 +1,5 @@
/* Autoscroll.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,10 +35,11 @@ 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.awt.dnd;
-import java.awt.Point;
import java.awt.Insets;
+import java.awt.Point;
/**
* During DnD operations it is possible that a user may wish to drop the
diff --git a/libjava/java/awt/dnd/DropTarget.java b/libjava/java/awt/dnd/DropTarget.java
index 4063e206a2b..7379ca71c0d 100644
--- a/libjava/java/awt/dnd/DropTarget.java
+++ b/libjava/java/awt/dnd/DropTarget.java
@@ -1,5 +1,5 @@
/* DropTarget.java --
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,12 +35,13 @@ 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.awt.dnd;
-import java.awt.Point;
import java.awt.Component;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
+import java.awt.Point;
import java.awt.datatransfer.FlavorMap;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
diff --git a/libjava/java/awt/dnd/DropTargetContext.java b/libjava/java/awt/dnd/DropTargetContext.java
index 4301fbccc85..d61785545c9 100644
--- a/libjava/java/awt/dnd/DropTargetContext.java
+++ b/libjava/java/awt/dnd/DropTargetContext.java
@@ -1,5 +1,5 @@
/* DropTargetContext.java --
- Copyright (C) 2002, 2003 Free Software Foundation
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -37,13 +37,12 @@ exception statement from your version. */
package java.awt.dnd;
-import java.awt.dnd.peer.DropTargetContextPeer;
-import java.io.Serializable;
-import java.io.IOException;
import java.awt.Component;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
diff --git a/libjava/java/awt/dnd/DropTargetDragEvent.java b/libjava/java/awt/dnd/DropTargetDragEvent.java
index e95b2d1ae87..d4a13ea4641 100644
--- a/libjava/java/awt/dnd/DropTargetDragEvent.java
+++ b/libjava/java/awt/dnd/DropTargetDragEvent.java
@@ -1,5 +1,5 @@
/* DropTargetDragEvent.java --
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,11 +35,12 @@ 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.awt.dnd;
-import java.util.List;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
+import java.util.List;
/**
* @since 1.2
diff --git a/libjava/java/awt/dnd/peer/DropTargetContextPeer.java b/libjava/java/awt/dnd/peer/DropTargetContextPeer.java
index 239a43778b8..a2e3ba2189f 100644
--- a/libjava/java/awt/dnd/peer/DropTargetContextPeer.java
+++ b/libjava/java/awt/dnd/peer/DropTargetContextPeer.java
@@ -1,5 +1,5 @@
/* DropTargetContextPeer.java -- interface for drag-and-drop peers
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,11 +35,12 @@ 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.awt.dnd.peer;
-import java.awt.dnd.DropTarget;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DropTarget;
import java.awt.dnd.InvalidDnDOperationException;
diff --git a/libjava/java/awt/event/ActionListener.java b/libjava/java/awt/event/ActionListener.java
index 40112080e53..71fdd2fd9e4 100644
--- a/libjava/java/awt/event/ActionListener.java
+++ b/libjava/java/awt/event/ActionListener.java
@@ -43,7 +43,7 @@ import java.util.EventListener;
/**
* This interface is for classes that listen for action events.
*
- * @author Aaron M. Renn <arenn@urbanophile.com>
+ * @author Aaron M. Renn (arenn@urbanophile.com)
* @see ActionEvent
* @since 1.1
* @status updated to 1.4
@@ -55,5 +55,5 @@ public interface ActionListener extends EventListener
*
* @param event the <code>ActionEvent</code> that occurred
*/
- void actionPerformed(ActionEvent e);
-} // interface ActionListener
+ void actionPerformed(ActionEvent event);
+}
diff --git a/libjava/java/awt/event/AdjustmentEvent.java b/libjava/java/awt/event/AdjustmentEvent.java
index 48b208b5d86..623dab5eaed 100644
--- a/libjava/java/awt/event/AdjustmentEvent.java
+++ b/libjava/java/awt/event/AdjustmentEvent.java
@@ -1,5 +1,5 @@
/* AdjustmentEvent.java -- an adjustable value was changed
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,8 @@ exception statement from your version. */
package java.awt.event;
-import java.awt.Adjustable;
import java.awt.AWTEvent;
+import java.awt.Adjustable;
/**
* This class represents an event that is generated when an adjustable
diff --git a/libjava/java/awt/event/HierarchyBoundsAdapter.java b/libjava/java/awt/event/HierarchyBoundsAdapter.java
index 5f807b38c9e..2f479fc23d2 100644
--- a/libjava/java/awt/event/HierarchyBoundsAdapter.java
+++ b/libjava/java/awt/event/HierarchyBoundsAdapter.java
@@ -63,7 +63,7 @@ public abstract class HierarchyBoundsAdapter implements HierarchyBoundsListener
*
* @param event the event, ignored in this implementation
*/
- public void ancestorMoved(HierarchyEvent e)
+ public void ancestorMoved(HierarchyEvent event)
{
}
@@ -72,7 +72,7 @@ public abstract class HierarchyBoundsAdapter implements HierarchyBoundsListener
*
* @param event the event, ignored in this implementation
*/
- public void ancestorResized(HierarchyEvent e)
+ public void ancestorResized(HierarchyEvent event)
{
}
-} // class HierarchyBoundsAdapter
+}
diff --git a/libjava/java/awt/event/InputEvent.java b/libjava/java/awt/event/InputEvent.java
index 1689e51143d..b2a1e3114ec 100644
--- a/libjava/java/awt/event/InputEvent.java
+++ b/libjava/java/awt/event/InputEvent.java
@@ -1,5 +1,5 @@
/* InputEvent.java -- common superclass of component input events
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,9 +38,10 @@ exception statement from your version. */
package java.awt.event;
-import java.awt.Component;
import gnu.java.awt.EventModifier;
+import java.awt.Component;
+
/**
* This is the common superclass for all component input classes. These are
* passed to listeners before the component, so that listeners can consume
@@ -349,6 +350,7 @@ public abstract class InputEvent extends ComponentEvent
* XXX Sun claims this can be localized via the awt.properties file - how
* do we implement that?
*
+ * @param modifiers the modifiers
* @return a string representation of the modifiers in this bitmask
* @since 1.4
*/
diff --git a/libjava/java/awt/event/InvocationEvent.java b/libjava/java/awt/event/InvocationEvent.java
index 76d4a558244..fb58595c793 100644
--- a/libjava/java/awt/event/InvocationEvent.java
+++ b/libjava/java/awt/event/InvocationEvent.java
@@ -1,5 +1,5 @@
/* InvocationEvent.java -- call a runnable when dispatched
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,8 @@ exception statement from your version. */
package java.awt.event;
-import java.awt.ActiveEvent;
import java.awt.AWTEvent;
+import java.awt.ActiveEvent;
import java.awt.EventQueue;
/**
diff --git a/libjava/java/awt/event/KeyEvent.java b/libjava/java/awt/event/KeyEvent.java
index 455d7ee5266..7212c0c9791 100644
--- a/libjava/java/awt/event/KeyEvent.java
+++ b/libjava/java/awt/event/KeyEvent.java
@@ -1,5 +1,5 @@
/* KeyEvent.java -- event for key presses
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,10 +38,11 @@ exception statement from your version. */
package java.awt.event;
+import gnu.java.awt.EventModifier;
+
import java.awt.Component;
import java.io.IOException;
import java.io.ObjectInputStream;
-import gnu.java.awt.EventModifier;
/**
* This event is generated when a key is pressed or released. There are two
diff --git a/libjava/java/awt/event/MouseEvent.java b/libjava/java/awt/event/MouseEvent.java
index ac8804c24d3..7f3e014a2ea 100644
--- a/libjava/java/awt/event/MouseEvent.java
+++ b/libjava/java/awt/event/MouseEvent.java
@@ -1,5 +1,5 @@
/* MouseEvent.java -- a mouse event
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,11 +38,12 @@ exception statement from your version. */
package java.awt.event;
+import gnu.java.awt.EventModifier;
+
import java.awt.Component;
import java.awt.Point;
import java.io.IOException;
import java.io.ObjectInputStream;
-import gnu.java.awt.EventModifier;
/**
* This event is generated for a mouse event. There are three main categories
diff --git a/libjava/java/awt/font/TextAttribute.java b/libjava/java/awt/font/TextAttribute.java
index c30f5fbe7ae..7d5444677a9 100644
--- a/libjava/java/awt/font/TextAttribute.java
+++ b/libjava/java/awt/font/TextAttribute.java
@@ -1,5 +1,5 @@
-/* TextAttribute.java
- Copyright (C) 2003 Free Software Foundation, Inc.
+/* TextAttribute.java --
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -70,19 +70,19 @@ public final class TextAttribute extends AttributedCharacterIterator.Attribute
public static final Float POSTURE_REGULAR = new Float (0.0);
public static final TextAttribute RUN_DIRECTION =
new TextAttribute ("RUN_DIRECTION");
- public static final Boolean RUN_DIRECTION_LTR = new Boolean (true);
- public static final Boolean RUN_DIRECTION_RTL = new Boolean (false);
+ public static final Boolean RUN_DIRECTION_LTR = Boolean.TRUE;
+ public static final Boolean RUN_DIRECTION_RTL = Boolean.FALSE;
public static final TextAttribute SIZE = new TextAttribute ("SIZE");
public static final TextAttribute STRIKETHROUGH =
new TextAttribute ("STRIKETHROUGH");
- public static final Boolean STRIKETHROUGH_ON = new Boolean (true);
+ public static final Boolean STRIKETHROUGH_ON = Boolean.TRUE;
public static final TextAttribute SUPERSCRIPT =
new TextAttribute ("SUPERSCRIPT");
public static final Integer SUPERSCRIPT_SUB = new Integer (-1);
public static final Integer SUPERSCRIPT_SUPER = new Integer (1);
public static final TextAttribute SWAP_COLORS =
new TextAttribute ("SWAP_COLORS");
- public static final Boolean SWAP_COLORS_ON = new Boolean (true);
+ public static final Boolean SWAP_COLORS_ON = Boolean.TRUE;
public static final TextAttribute TRANSFORM = new TextAttribute ("TRANSFORM");
public static final TextAttribute UNDERLINE = new TextAttribute ("UNDERLINE");
public static final Integer UNDERLINE_LOW_DASHED = new Integer (0);
diff --git a/libjava/java/awt/font/TextLayout.java b/libjava/java/awt/font/TextLayout.java
index b58b5a58349..7d6c4d8c635 100644
--- a/libjava/java/awt/font/TextLayout.java
+++ b/libjava/java/awt/font/TextLayout.java
@@ -1,5 +1,5 @@
-/* TextLayout.java
- Copyright (C) 2003 Free Software Foundation, Inc.
+/* TextLayout.java --
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,17 +38,18 @@ exception statement from your version. */
package java.awt.font;
+import gnu.java.awt.ClasspathToolkit;
+import gnu.java.awt.peer.ClasspathTextLayoutPeer;
+
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Shape;
+import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
-import java.text.CharacterIterator;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.Map;
-import java.awt.font.TextAttribute;
-
/**
* @author Michael Koch
@@ -56,6 +57,7 @@ import java.awt.font.TextAttribute;
public final class TextLayout implements Cloneable
{
public static final CaretPolicy DEFAULT_CARET_POLICY = new CaretPolicy ();
+ ClasspathTextLayoutPeer peer;
public static class CaretPolicy
{
@@ -67,37 +69,39 @@ public final class TextLayout implements Cloneable
public TextHitInfo getStrongCaret (TextHitInfo hit1, TextHitInfo hit2,
TextLayout layout)
{
- throw new Error ("not implemented");
+ return layout.peer.getStrongCaret(hit1, hit2);
}
}
- private AttributedString attributedString;
- private FontRenderContext fontRenderContext;
-
public TextLayout (AttributedCharacterIterator text, FontRenderContext frc)
{
- attributedString = new AttributedString (text);
- fontRenderContext = frc;
+ AttributedString as = new AttributedString (text);
+ ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
+ peer = tk.getClasspathTextLayoutPeer(as, frc);
}
public TextLayout (String string, Font font, FontRenderContext frc)
{
- attributedString = new AttributedString (string);
- attributedString.addAttribute (TextAttribute.FONT, font);
- fontRenderContext = frc;
+ AttributedString as = new AttributedString (string);
+ as.addAttribute (TextAttribute.FONT, font);
+ ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
+ peer = tk.getClasspathTextLayoutPeer(as, frc);
}
- public TextLayout (String string, Map attributes, FontRenderContext frc)
+ public TextLayout (String string, Map attributes, FontRenderContext frc)
{
- attributedString = new AttributedString (string, attributes);
- fontRenderContext = frc;
+ AttributedString as = new AttributedString (string, attributes);
+ ClasspathToolkit tk = (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
+ peer = tk.getClasspathTextLayoutPeer(as, frc);
}
protected Object clone ()
{
try
{
- return super.clone ();
+ TextLayout tl = (TextLayout) super.clone ();
+ tl.peer = (ClasspathTextLayoutPeer) this.peer.clone();
+ return tl;
}
catch (CloneNotSupportedException e)
{
@@ -107,146 +111,9 @@ public final class TextLayout implements Cloneable
}
- protected class CharacterIteratorProxy
- implements CharacterIterator
- {
- public CharacterIterator target;
- public int begin;
- public int limit;
- public int index;
-
- public CharacterIteratorProxy (CharacterIterator ci)
- {
- target = ci;
- }
-
- public int getBeginIndex ()
- {
- return begin;
- }
-
- public int getEndIndex ()
- {
- return limit;
- }
-
- public int getIndex ()
- {
- return index;
- }
-
- public char setIndex (int idx)
- throws IllegalArgumentException
- {
- if (idx < begin || idx >= limit)
- throw new IllegalArgumentException ();
- char ch = target.setIndex (idx);
- index = idx;
- return ch;
- }
-
- public char first ()
- {
- int save = target.getIndex ();
- char ch = target.setIndex (begin);
- target.setIndex (save);
- return ch;
- }
-
- public char last ()
- {
- if (begin == limit)
- return this.first ();
-
- int save = target.getIndex ();
- char ch = target.setIndex (limit - 1);
- target.setIndex (save);
- return ch;
- }
-
- public char current ()
- {
- return target.current();
- }
-
- public char next ()
- {
- if (index >= limit - 1)
- return CharacterIterator.DONE;
- else
- {
- index++;
- return target.next();
- }
- }
-
- public char previous ()
- {
- if (index <= begin)
- return CharacterIterator.DONE;
- else
- {
- index--;
- return target.previous ();
- }
- }
-
- public Object clone ()
- {
- CharacterIteratorProxy cip = new CharacterIteratorProxy (this.target);
- cip.begin = this.begin;
- cip.limit = this.limit;
- cip.index = this.index;
- return cip;
- }
-
- }
-
-
public void draw (Graphics2D g2, float x, float y)
{
- AttributedCharacterIterator ci = attributedString.getIterator ();
- CharacterIteratorProxy proxy = new CharacterIteratorProxy (ci);
- Font defFont = g2.getFont ();
-
- /* Note: this implementation currently only interprets FONT text
- * attributes. There is a reasonable argument to be made for some
- * attributes being interpreted out here, where we have control of the
- * Graphics2D and can construct or derive new fonts, and some
- * attributes being interpreted by the GlyphVector itself. So far, for
- * all attributes except FONT we do neither.
- */
-
- for (char c = ci.first ();
- c != CharacterIterator.DONE;
- c = ci.next ())
- {
- proxy.begin = ci.getIndex ();
- proxy.limit = ci.getRunLimit(TextAttribute.FONT);
- if (proxy.limit <= proxy.begin)
- continue;
-
- proxy.index = proxy.begin;
-
- Object fnt = ci.getAttribute(TextAttribute.FONT);
- GlyphVector gv;
- if (fnt instanceof Font)
- gv = ((Font)fnt).createGlyphVector (fontRenderContext, proxy);
- else
- gv = defFont.createGlyphVector (fontRenderContext, proxy);
-
- g2.drawGlyphVector (gv, x, y);
-
- int n = gv.getNumGlyphs ();
- for (int i = 0; i < n; ++i)
- {
- GlyphMetrics gm = gv.getGlyphMetrics (i);
- if (gm.getAdvanceX() == gm.getAdvance ())
- x += gm.getAdvanceX ();
- else
- y += gm.getAdvanceY ();
- }
- }
+ peer.draw(g2, x, y);
}
public boolean equals (Object obj)
@@ -259,207 +126,207 @@ public final class TextLayout implements Cloneable
public boolean equals (TextLayout tl)
{
- throw new Error ("not implemented");
+ return this.peer.equals(tl.peer);
}
public float getAdvance ()
{
- throw new Error ("not implemented");
+ return peer.getAdvance();
}
public float getAscent ()
{
- throw new Error ("not implemented");
+ return peer.getAscent();
}
public byte getBaseline ()
{
- throw new Error ("not implemented");
+ return peer.getBaseline();
}
public float[] getBaselineOffsets ()
{
- throw new Error ("not implemented");
+ return peer.getBaselineOffsets();
}
public Shape getBlackBoxBounds (int firstEndpoint, int secondEndpoint)
{
- throw new Error ("not implemented");
+ return peer.getBlackBoxBounds(firstEndpoint, secondEndpoint);
}
public Rectangle2D getBounds()
{
- throw new Error ("not implemented");
+ return peer.getBounds();
}
public float[] getCaretInfo (TextHitInfo hit)
{
- throw new Error ("not implemented");
+ return getCaretInfo(hit, getBounds());
}
public float[] getCaretInfo (TextHitInfo hit, Rectangle2D bounds)
{
- throw new Error ("not implemented");
+ return peer.getCaretInfo(hit, bounds);
}
public Shape getCaretShape (TextHitInfo hit)
{
- throw new Error ("not implemented");
+ return getCaretShape(hit, getBounds());
}
public Shape getCaretShape (TextHitInfo hit, Rectangle2D bounds)
{
- throw new Error ("not implemented");
+ return peer.getCaretShape(hit, bounds);
}
public Shape[] getCaretShapes (int offset)
{
- throw new Error ("not implemented");
+ return getCaretShapes(offset, getBounds());
}
public Shape[] getCaretShapes (int offset, Rectangle2D bounds)
{
- throw new Error ("not implemented");
+ return getCaretShapes(offset, getBounds(), DEFAULT_CARET_POLICY);
}
public Shape[] getCaretShapes (int offset, Rectangle2D bounds,
TextLayout.CaretPolicy policy)
{
- throw new Error ("not implemented");
+ return peer.getCaretShapes(offset, bounds, policy);
}
public int getCharacterCount ()
{
- throw new Error ("not implemented");
+ return peer.getCharacterCount();
}
public byte getCharacterLevel (int index)
{
- throw new Error ("not implemented");
+ return peer.getCharacterLevel(index);
}
public float getDescent ()
{
- throw new Error ("not implemented");
+ return peer.getDescent();
}
public TextLayout getJustifiedLayout (float justificationWidth)
{
- throw new Error ("not implemented");
+ return peer.getJustifiedLayout(justificationWidth);
}
public float getLeading ()
{
- throw new Error ("not implemented");
+ return peer.getLeading();
}
public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint)
{
- throw new Error ("not implemented");
+ return getLogicalHighlightShape (firstEndpoint, secondEndpoint, getBounds());
}
public Shape getLogicalHighlightShape (int firstEndpoint, int secondEndpoint,
Rectangle2D bounds)
{
- throw new Error ("not implemented");
+ return peer.getLogicalHighlightShape(firstEndpoint, secondEndpoint, bounds);
}
public int[] getLogicalRangesForVisualSelection (TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint)
{
- throw new Error ("not implemented");
+ return peer.getLogicalRangesForVisualSelection(firstEndpoint, secondEndpoint);
}
public TextHitInfo getNextLeftHit (int offset)
{
- throw new Error ("not implemented");
+ return getNextLeftHit(offset, DEFAULT_CARET_POLICY);
}
public TextHitInfo getNextLeftHit (int offset, TextLayout.CaretPolicy policy)
{
- throw new Error ("not implemented");
+ return peer.getNextLeftHit(offset, policy);
}
public TextHitInfo getNextLeftHit (TextHitInfo hit)
{
- throw new Error ("not implemented");
+ return getNextLeftHit(hit.getCharIndex());
}
public TextHitInfo getNextRightHit (int offset)
{
- throw new Error ("not implemented");
+ return getNextRightHit(offset, DEFAULT_CARET_POLICY);
}
public TextHitInfo getNextRightHit (int offset, TextLayout.CaretPolicy policy)
{
- throw new Error ("not implemented");
+ return peer.getNextRightHit(offset, policy);
}
public TextHitInfo getNextRightHit (TextHitInfo hit)
{
- throw new Error ("not implemented");
+ return getNextRightHit(hit.getCharIndex());
}
public Shape getOutline (AffineTransform tx)
{
- throw new Error ("not implemented");
+ return peer.getOutline(tx);
}
public float getVisibleAdvance ()
{
- throw new Error ("not implemented");
+ return peer.getVisibleAdvance();
}
public Shape getVisualHighlightShape (TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint)
{
- throw new Error ("not implemented");
+ return getVisualHighlightShape(firstEndpoint, secondEndpoint, getBounds());
}
public Shape getVisualHighlightShape (TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint,
Rectangle2D bounds)
{
- throw new Error ("not implemented");
+ return peer.getVisualHighlightShape(firstEndpoint, secondEndpoint, bounds);
}
public TextHitInfo getVisualOtherHit (TextHitInfo hit)
{
- throw new Error ("not implemented");
+ return peer.getVisualOtherHit(hit);
}
protected void handleJustify (float justificationWidth)
{
- throw new Error ("not implemented");
+ peer.handleJustify(justificationWidth);
}
public int hashCode ()
{
- throw new Error ("not implemented");
+ return peer.hashCode();
}
public TextHitInfo hitTestChar (float x, float y)
{
- throw new Error ("not implemented");
+ return hitTestChar(x, y, getBounds());
}
public TextHitInfo hitTestChar (float x, float y, Rectangle2D bounds)
{
- throw new Error ("not implemented");
+ return peer.hitTestChar(x, y, bounds);
}
public boolean isLeftToRight ()
{
- throw new Error ("not implemented");
+ return peer.isLeftToRight();
}
public boolean isVertical ()
{
- throw new Error ("not implemented");
+ return peer.isVertical();
}
public String toString ()
{
- throw new Error ("not implemented");
+ return peer.toString();
}
}
diff --git a/libjava/java/awt/geom/AffineTransform.java b/libjava/java/awt/geom/AffineTransform.java
index 1410d90cb37..21eacae7409 100644
--- a/libjava/java/awt/geom/AffineTransform.java
+++ b/libjava/java/awt/geom/AffineTransform.java
@@ -1,5 +1,5 @@
/* AffineTransform.java -- transform coordinates between two 2-D spaces
- Copyright (C) 2000, 2001, 2002 Free Software Foundation
+ Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -57,10 +57,11 @@ import java.io.Serializable;
* [ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ]
* </pre>
* The bottom row of the matrix is constant, so a transform can be uniquely
- * represented (as in toString) by "[[m00, m01, m02], [m10, m11, m12]]".
+ * represented (as in {@link #toString()}) by
+ * "[[m00, m01, m02], [m10, m11, m12]]".
*
- * @author Tom Tromey <tromey@cygnus.com>
- * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
* @since 1.2
* @status partially updated to 1.4, still has some problems
*/
@@ -517,6 +518,8 @@ public class AffineTransform implements Cloneable, Serializable
* or a bit-wise combination of TYPE_TRANSLATION, the mutually exclusive
* TYPE_*_ROTATIONs, and the mutually exclusive TYPE_*_SCALEs.
*
+ * @return The type.
+ *
* @see #TYPE_IDENTITY
* @see #TYPE_TRANSLATION
* @see #TYPE_UNIFORM_SCALE
@@ -1105,9 +1108,9 @@ public class AffineTransform implements Cloneable, Serializable
* transformation, so that no result will overwrite a point that has not yet
* been evaluated.
*
- * @param src the array of source points
+ * @param srcPts the array of source points
* @param srcOff the starting offset into src
- * @param dst the array of destination points
+ * @param dstPts the array of destination points
* @param dstOff the starting offset into dst
* @param num the number of points to transform
* @throws NullPointerException if src or dst is null
@@ -1139,9 +1142,9 @@ public class AffineTransform implements Cloneable, Serializable
* transformation, so that no result will overwrite a point that has not yet
* been evaluated.
*
- * @param src the array of source points
+ * @param srcPts the array of source points
* @param srcOff the starting offset into src
- * @param dst the array of destination points
+ * @param dstPts the array of destination points
* @param dstOff the starting offset into dst
* @param num the number of points to transform
* @throws NullPointerException if src or dst is null
@@ -1171,9 +1174,9 @@ public class AffineTransform implements Cloneable, Serializable
* storing the results in another array. This will not create a destination
* array.
*
- * @param src the array of source points
+ * @param srcPts the array of source points
* @param srcOff the starting offset into src
- * @param dst the array of destination points
+ * @param dstPts the array of destination points
* @param dstOff the starting offset into dst
* @param num the number of points to transform
* @throws NullPointerException if src or dst is null
@@ -1196,9 +1199,9 @@ public class AffineTransform implements Cloneable, Serializable
* storing the results in another array. This will not create a destination
* array.
*
- * @param src the array of source points
+ * @param srcPts the array of source points
* @param srcOff the starting offset into src
- * @param dst the array of destination points
+ * @param dstPts the array of destination points
* @param dstOff the starting offset into dst
* @param num the number of points to transform
* @throws NullPointerException if src or dst is null
@@ -1231,17 +1234,7 @@ public class AffineTransform implements Cloneable, Serializable
public Point2D inverseTransform(Point2D src, Point2D dst)
throws NoninvertibleTransformException
{
- double det = getDeterminant();
- if (det == 0)
- throw new NoninvertibleTransformException("couldn't invert transform");
- if (dst == null)
- dst = new Point2D.Double();
- double x = src.getX();
- double y = src.getY();
- double nx = (m11 * x + -m10 * y) / det - m02;
- double ny = (m01 * x + -m00 * y) / det - m12;
- dst.setLocation(nx, ny);
- return dst;
+ return createInverse().transform(src, dst);
}
/**
@@ -1251,9 +1244,9 @@ public class AffineTransform implements Cloneable, Serializable
* transformation, so that no result will overwrite a point that has not yet
* been evaluated.
*
- * @param src the array of source points
+ * @param srcPts the array of source points
* @param srcOff the starting offset into src
- * @param dst the array of destination points
+ * @param dstPts the array of destination points
* @param dstOff the starting offset into dst
* @param num the number of points to transform
* @throws NullPointerException if src or dst is null
@@ -1265,23 +1258,7 @@ public class AffineTransform implements Cloneable, Serializable
double[] dstPts, int dstOff, int num)
throws NoninvertibleTransformException
{
- double det = getDeterminant();
- if (det == 0)
- throw new NoninvertibleTransformException("couldn't invert transform");
- if (srcPts == dstPts && dstOff > srcOff
- && num > 1 && srcOff + 2 * num > dstOff)
- {
- double[] d = new double[2 * num];
- System.arraycopy(srcPts, srcOff, d, 0, 2 * num);
- srcPts = d;
- }
- while (--num >= 0)
- {
- double x = srcPts[srcOff++];
- double y = srcPts[srcOff++];
- dstPts[dstOff++] = (m11 * x + -m10 * y) / det - m02;
- dstPts[dstOff++] = (m01 * x + -m00 * y) / det - m12;
- }
+ createInverse().transform(srcPts, srcOff, dstPts, dstOff, num);
}
/**
@@ -1322,9 +1299,9 @@ public class AffineTransform implements Cloneable, Serializable
* [ y' ] [ m10 m11 ] [ y ] = [ m10 * x + m11 * y ]
* </pre>
*
- * @param src the array of source points
+ * @param srcPts the array of source points
* @param srcOff the starting offset into src
- * @param dst the array of destination points
+ * @param dstPts the array of destination points
* @param dstOff the starting offset into dst
* @param num the number of points to transform
* @throws NullPointerException if src or dst is null
@@ -1356,12 +1333,14 @@ public class AffineTransform implements Cloneable, Serializable
* which only stores points in float precision.
*
* @param src the shape source to transform
- * @return the shape, transformed by this
- * @throws NullPointerException if src is null
+ * @return the shape, transformed by this, <code>null</code> if src is
+ * <code>null</code>.
* @see GeneralPath#transform(AffineTransform)
*/
public Shape createTransformedShape(Shape src)
{
+ if(src == null)
+ return null;
GeneralPath p = new GeneralPath(src);
p.transform(this);
return p;
@@ -1445,7 +1424,7 @@ public class AffineTransform implements Cloneable, Serializable
* Compares two transforms for equality. This returns true if they have the
* same matrix values.
*
- * @param o the transform to compare
+ * @param obj the transform to compare
* @return true if it is equal
*/
public boolean equals(Object obj)
diff --git a/libjava/java/awt/geom/Arc2D.java b/libjava/java/awt/geom/Arc2D.java
index 64d81650bfe..5ce3b08e82f 100644
--- a/libjava/java/awt/geom/Arc2D.java
+++ b/libjava/java/awt/geom/Arc2D.java
@@ -1,5 +1,5 @@
/* Arc2D.java -- represents an arc in 2-D space
- Copyright (C) 2002, 2003 Free Software Foundation
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -35,11 +35,11 @@ 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.awt.geom;
import java.util.NoSuchElementException;
+
/**
* This class represents all arcs (segments of an ellipse in 2-D space). The
* arcs are defined by starting angle and extent (arc length) in degrees, as
@@ -51,8 +51,8 @@ import java.util.NoSuchElementException;
* first 360 degrees. Storage is up to the subclasses.
*
* @author Eric Blake (ebb9@email.byu.edu)
+ * @author Sven de Marothy (sven@physto.se)
* @since 1.2
- * @status updated to 1.4, but still missing functionality
*/
public abstract class Arc2D extends RectangularShape
{
@@ -154,8 +154,8 @@ public abstract class Arc2D extends RectangularShape
* extent sweeps counterclockwise (from the positive x-axis to the negative
* y-axis).
*
- * @param x the new x coordinate of the lower left of the bounding box
- * @param y the new y coordinate of the lower left of the bounding box
+ * @param x the new x coordinate of the upper left of the bounding box
+ * @param y the new y coordinate of the upper left of the bounding box
* @param w the new width of the bounding box
* @param h the new height of the bounding box
* @param start the start angle, in degrees
@@ -171,7 +171,7 @@ public abstract class Arc2D extends RectangularShape
* extent sweeps counterclockwise (from the positive x-axis to the negative
* y-axis).
*
- * @param p the lower left point of the bounding box
+ * @param p the upper left point of the bounding box
* @param d the dimensions of the bounding box
* @param start the start angle, in degrees
* @param extent the arc extent, in degrees
@@ -179,11 +179,10 @@ public abstract class Arc2D extends RectangularShape
* @throws IllegalArgumentException if type is invalid
* @throws NullPointerException if p or d is null
*/
- public void setArc(Point2D p, Dimension2D d,
- double start, double extent, int type)
+ public void setArc(Point2D p, Dimension2D d, double start, double extent,
+ int type)
{
- setArc(p.getX(), p.getY(), d.getWidth(), d.getHeight(),
- start, extent, type);
+ setArc(p.getX(), p.getY(), d.getWidth(), d.getHeight(), start, extent, type);
}
/**
@@ -200,8 +199,7 @@ public abstract class Arc2D extends RectangularShape
*/
public void setArc(Rectangle2D r, double start, double extent, int type)
{
- setArc(r.getX(), r.getY(), r.getWidth(), r.getHeight(),
- start, extent, type);
+ setArc(r.getX(), r.getY(), r.getWidth(), r.getHeight(), start, extent, type);
}
/**
@@ -212,8 +210,8 @@ public abstract class Arc2D extends RectangularShape
*/
public void setArc(Arc2D a)
{
- setArc(a.getX(), a.getY(), a.getWidth(), a.getHeight(),
- a.getAngleStart(), a.getAngleExtent(), a.getArcType());
+ setArc(a.getX(), a.getY(), a.getWidth(), a.getHeight(), a.getAngleStart(),
+ a.getAngleExtent(), a.getArcType());
}
/**
@@ -230,8 +228,8 @@ public abstract class Arc2D extends RectangularShape
* @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
* @throws IllegalArgumentException if type is invalid
*/
- public void setArcByCenter(double x, double y, double r,
- double start, double extent, int type)
+ public void setArcByCenter(double x, double y, double r, double start,
+ double extent, int type)
{
setArc(x - r, y - r, r + r, r + r, start, extent, type);
}
@@ -252,8 +250,50 @@ public abstract class Arc2D extends RectangularShape
*/
public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double r)
{
- // XXX Implement.
- throw new Error("not implemented");
+ if ((p2.getX() - p1.getX()) * (p3.getY() - p1.getY())
+ - (p3.getX() - p1.getX()) * (p2.getY() - p1.getY()) > 0)
+ {
+ Point2D p = p3;
+ p3 = p1;
+ p1 = p;
+ }
+
+ // normalized tangent vectors
+ double dx1 = (p1.getX() - p2.getX()) / p1.distance(p2);
+ double dy1 = (p1.getY() - p2.getY()) / p1.distance(p2);
+ double dx2 = (p2.getX() - p3.getX()) / p3.distance(p2);
+ double dy2 = (p2.getY() - p3.getY()) / p3.distance(p2);
+ double theta1 = Math.atan2(dx1, dy1);
+ double theta2 = Math.atan2(dx2, dy2);
+
+ double dx = r * Math.cos(theta2) - r * Math.cos(theta1);
+ double dy = -r * Math.sin(theta2) + r * Math.sin(theta1);
+
+ if (theta1 < 0)
+ theta1 += 2 * Math.PI;
+ if (theta2 < 0)
+ theta2 += 2 * Math.PI;
+ if (theta2 < theta1)
+ theta2 += 2 * Math.PI;
+
+ // Vectors of the lines, not normalized, note we change
+ // the direction of line 2.
+ dx1 = p1.getX() - p2.getX();
+ dy1 = p1.getY() - p2.getY();
+ dx2 = p3.getX() - p2.getX();
+ dy2 = p3.getY() - p2.getY();
+
+ // Calculate the tangent point to the second line
+ double t2 = -(dx1 * dy - dy1 * dx) / (dx2 * dy1 - dx1 * dy2);
+ double x2 = t2 * (p3.getX() - p2.getX()) + p2.getX();
+ double y2 = t2 * (p3.getY() - p2.getY()) + p2.getY();
+
+ // calculate the center point
+ double x = x2 - r * Math.cos(theta2);
+ double y = y2 + r * Math.sin(theta2);
+
+ setArc(x - r, y - r, 2 * r, 2 * r, Math.toDegrees(theta1),
+ Math.toDegrees(theta2 - theta1), getArcType());
}
/**
@@ -287,7 +327,7 @@ public abstract class Arc2D extends RectangularShape
// Normalize.
double x = p.getX() - (getX() + getWidth() / 2);
double y = p.getY() - (getY() + getHeight() / 2);
- setAngleStart(Math.toDegrees(Math.atan2(y, x)));
+ setAngleStart(Math.toDegrees(Math.atan2(-y, x)));
}
/**
@@ -312,8 +352,8 @@ public abstract class Arc2D extends RectangularShape
y1 = y1 - (my + mh / 2);
x2 = x2 - (mx + mw / 2);
y2 = y2 - (my + mh / 2);
- double start = Math.toDegrees(Math.atan2(y1, x1));
- double extent = Math.toDegrees(Math.atan2(y2, x2)) - start;
+ double start = Math.toDegrees(Math.atan2(-y1, x1));
+ double extent = Math.toDegrees(Math.atan2(-y2, x2)) - start;
if (extent < 0)
extent += 360;
setAngleStart(start);
@@ -413,8 +453,8 @@ public abstract class Arc2D extends RectangularShape
* @param h the height
* @return the rectangle for use in getBounds2D
*/
- protected abstract Rectangle2D makeBounds(double x, double y,
- double w, double h);
+ protected abstract Rectangle2D makeBounds(double x, double y, double w,
+ double h);
/**
* Tests if the given angle, in degrees, is included in the arc.
@@ -426,27 +466,44 @@ public abstract class Arc2D extends RectangularShape
public boolean containsAngle(double a)
{
double start = getAngleStart();
- double end = start + getAngleExtent();
+ double extent = getAngleExtent();
+ double end = start + extent;
+
+ if (extent == 0)
+ return false;
+
+ if (extent >= 360 || extent <= -360)
+ return true;
+
+ if (extent < 0)
+ {
+ end = start;
+ start += extent;
+ }
start %= 360;
- if (start < 0)
+ while (start < 0)
start += 360;
end %= 360;
- if (end < 0)
+ while (end < start)
end += 360;
a %= 360;
- if (a < 0)
+ while (a < start)
a += 360;
- return a >= start && a <= end;
+ return a >= start && a < end; // starting angle included, ending angle not
}
/**
* Determines if the arc contains the given point. If the bounding box
* is empty, then this will return false.
*
+ * The area considered 'inside' an arc of type OPEN is the same as the
+ * area inside an equivalent filled CHORD-type arc. The area considered
+ * 'inside' a CHORD-type arc is the same as the filled area.
+ *
* @param x the x coordinate to test
* @param y the y coordinate to test
* @return true if the point is inside the arc
@@ -455,15 +512,50 @@ public abstract class Arc2D extends RectangularShape
{
double w = getWidth();
double h = getHeight();
- if (w <= 0 || h <= 0)
+ double extent = getAngleExtent();
+ if (w <= 0 || h <= 0 || extent == 0)
return false;
- // XXX Finish implementing.
- throw new Error("not implemented");
+
+ double mx = getX() + w / 2;
+ double my = getY() + h / 2;
+ double dx = (x - mx) * 2 / w;
+ double dy = (y - my) * 2 / h;
+ if ((dx * dx + dy * dy) >= 1.0)
+ return false;
+
+ double angle = Math.toDegrees(Math.atan2(-dy, dx));
+ if (getArcType() == PIE)
+ return containsAngle(angle);
+
+ double a1 = Math.toRadians(getAngleStart());
+ double a2 = Math.toRadians(getAngleStart() + extent);
+ double x1 = mx + getWidth() * Math.cos(a1) / 2;
+ double y1 = my - getHeight() * Math.sin(a1) / 2;
+ double x2 = mx + getWidth() * Math.cos(a2) / 2;
+ double y2 = my - getHeight() * Math.sin(a2) / 2;
+ double sgn = ((x2 - x1) * (my - y1) - (mx - x1) * (y2 - y1)) * ((x2 - x1) * (y
+ - y1) - (x - x1) * (y2 - y1));
+
+ if (Math.abs(extent) > 180)
+ {
+ if (containsAngle(angle))
+ return true;
+ return sgn > 0;
+ }
+ else
+ {
+ if (! containsAngle(angle))
+ return false;
+ return sgn < 0;
+ }
}
/**
* Tests if a given rectangle intersects the area of the arc.
*
+ * For a definition of the 'inside' area, see the contains() method.
+ * @see #contains(double, double)
+ *
* @param x the x coordinate of the rectangle
* @param y the y coordinate of the rectangle
* @param w the width of the rectangle
@@ -472,12 +564,94 @@ public abstract class Arc2D extends RectangularShape
*/
public boolean intersects(double x, double y, double w, double h)
{
- double mw = getWidth();
- double mh = getHeight();
- if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0)
+ double extent = getAngleExtent();
+ if (extent == 0)
return false;
- // XXX Finish implementing.
- throw new Error("not implemented");
+
+ if (contains(x, y) || contains(x, y + h) || contains(x + w, y)
+ || contains(x + w, y + h))
+ return true;
+
+ Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
+
+ double a = getWidth() / 2.0;
+ double b = getHeight() / 2.0;
+
+ double mx = getX() + a;
+ double my = getY() + b;
+ double x1 = mx + a * Math.cos(Math.toRadians(getAngleStart()));
+ double y1 = my - b * Math.sin(Math.toRadians(getAngleStart()));
+ double x2 = mx + a * Math.cos(Math.toRadians(getAngleStart() + extent));
+ double y2 = my - b * Math.sin(Math.toRadians(getAngleStart() + extent));
+
+ if (getArcType() != CHORD)
+ {
+ // check intersections against the pie radii
+ if (rect.intersectsLine(mx, my, x1, y1))
+ return true;
+ if (rect.intersectsLine(mx, my, x2, y2))
+ return true;
+ }
+ else// check the chord
+ if (rect.intersectsLine(x1, y1, x2, y2))
+ return true;
+
+ // Check the Arc segment against the four edges
+ double dx;
+
+ // Check the Arc segment against the four edges
+ double dy;
+ dy = y - my;
+ dx = a * Math.sqrt(1 - ((dy * dy) / (b * b)));
+ if (! java.lang.Double.isNaN(dx))
+ {
+ if (mx + dx >= x && mx + dx <= x + w
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
+ return true;
+ if (mx - dx >= x && mx - dx <= x + w
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, -dx))))
+ return true;
+ }
+ dy = (y + h) - my;
+ dx = a * Math.sqrt(1 - ((dy * dy) / (b * b)));
+ if (! java.lang.Double.isNaN(dx))
+ {
+ if (mx + dx >= x && mx + dx <= x + w
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
+ return true;
+ if (mx - dx >= x && mx - dx <= x + w
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, -dx))))
+ return true;
+ }
+ dx = x - mx;
+ dy = b * Math.sqrt(1 - ((dx * dx) / (a * a)));
+ if (! java.lang.Double.isNaN(dy))
+ {
+ if (my + dy >= y && my + dy <= y + h
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
+ return true;
+ if (my - dy >= y && my - dy <= y + h
+ && containsAngle(Math.toDegrees(Math.atan2(dy, dx))))
+ return true;
+ }
+
+ dx = (x + w) - mx;
+ dy = b * Math.sqrt(1 - ((dx * dx) / (a * a)));
+ if (! java.lang.Double.isNaN(dy))
+ {
+ if (my + dy >= y && my + dy <= y + h
+ && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
+ return true;
+ if (my - dy >= y && my - dy <= y + h
+ && containsAngle(Math.toDegrees(Math.atan2(dy, dx))))
+ return true;
+ }
+
+ // Check whether the arc is contained within the box
+ if (rect.contains(mx, my))
+ return true;
+
+ return false;
}
/**
@@ -491,12 +665,37 @@ public abstract class Arc2D extends RectangularShape
*/
public boolean contains(double x, double y, double w, double h)
{
- double mw = getWidth();
- double mh = getHeight();
- if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0)
+ double extent = getAngleExtent();
+ if (extent == 0)
+ return false;
+
+ if (! (contains(x, y) && contains(x, y + h) && contains(x + w, y)
+ && contains(x + w, y + h)))
+ return false;
+
+ Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
+
+ double a = getWidth() / 2.0;
+ double b = getHeight() / 2.0;
+
+ double mx = getX() + a;
+ double my = getY() + b;
+ double x1 = mx + a * Math.cos(Math.toRadians(getAngleStart()));
+ double y1 = my - b * Math.sin(Math.toRadians(getAngleStart()));
+ double x2 = mx + a * Math.cos(Math.toRadians(getAngleStart() + extent));
+ double y2 = my - b * Math.sin(Math.toRadians(getAngleStart() + extent));
+ if (getArcType() != CHORD)
+ {
+ // check intersections against the pie radii
+ if (rect.intersectsLine(mx, my, x1, y1))
+ return false;
+
+ if (rect.intersectsLine(mx, my, x2, y2))
+ return false;
+ }
+ else if (rect.intersectsLine(x1, y1, x2, y2))
return false;
- // XXX Finish implementing.
- throw new Error("not implemented");
+ return true;
}
/**
@@ -567,29 +766,37 @@ public abstract class Arc2D extends RectangularShape
* @param a the arc
* @param xform the transform
*/
- ArcIterator(Arc2D a, AffineTransform xform)
+ public ArcIterator(Arc2D a, AffineTransform xform)
{
this.xform = xform;
x = a.getX();
y = a.getY();
w = a.getWidth();
h = a.getHeight();
- start = a.getAngleStart() * (Math.PI / 180);
- extent = a.getAngleExtent() * (Math.PI / 180);
+ double start = a.getAngleStart() * (Math.PI / 180);
+ double extent = a.getAngleExtent() * (Math.PI / 180);
+
+ if (extent < 0)
+ {
+ extent = -extent;
+ start = 2 * Math.PI - extent + start;
+ }
+ this.start = start;
+ this.extent = extent;
+
type = a.type;
- double e = extent < 0 ? -extent : extent;
if (w < 0 || h < 0)
- limit = -1;
- else if (e == 0)
- limit = type;
- else if (e <= Math.PI / 2.0)
- limit = type + 1;
- else if (e <= Math.PI)
- limit = type + 2;
- else if (e <= 3.0 * (Math.PI / 2.0))
- limit = type + 3;
+ limit = -1;
+ else if (extent == 0)
+ limit = type;
+ else if (extent <= Math.PI / 2.0)
+ limit = type + 1;
+ else if (extent <= Math.PI)
+ limit = type + 2;
+ else if (extent <= 3.0 * (Math.PI / 2.0))
+ limit = type + 3;
else
- limit = type + 4;
+ limit = type + 4;
}
/**
@@ -598,7 +805,7 @@ public abstract class Arc2D extends RectangularShape
* @param e the ellipse
* @param xform the transform
*/
- ArcIterator(Ellipse2D e, AffineTransform xform)
+ public ArcIterator(Ellipse2D e, AffineTransform xform)
{
this.xform = xform;
x = e.getX();
@@ -606,7 +813,7 @@ public abstract class Arc2D extends RectangularShape
w = e.getWidth();
h = e.getHeight();
start = 0;
- extent = -2 * Math.PI;
+ extent = 2 * Math.PI;
type = CHORD;
limit = (w < 0 || h < 0) ? -1 : 5;
}
@@ -650,9 +857,9 @@ public abstract class Arc2D extends RectangularShape
public int currentSegment(float[] coords)
{
double[] double_coords = new double[6];
- int code = currentSegment (double_coords);
+ int code = currentSegment(double_coords);
for (int i = 0; i < 6; ++i)
- coords[i] = (float) double_coords[i];
+ coords[i] = (float) double_coords[i];
return code;
}
@@ -666,48 +873,38 @@ public abstract class Arc2D extends RectangularShape
*/
public int currentSegment(double[] coords)
{
- double rx = w/2;
- double ry = h/2;
+ double rx = w / 2;
+ double ry = h / 2;
double xmid = x + rx;
double ymid = y + ry;
-
+
if (current > limit)
- throw new NoSuchElementException("arc iterator out of bounds");
+ throw new NoSuchElementException("arc iterator out of bounds");
if (current == 0)
{
- coords[0] = xmid + rx * Math.cos(start);
- coords[1] = ymid - ry * Math.sin(start);
- if (xform != null)
- xform.transform(coords, 0, coords, 0, 1);
- return SEG_MOVETO;
+ coords[0] = xmid + rx * Math.cos(start);
+ coords[1] = ymid - ry * Math.sin(start);
+ if (xform != null)
+ xform.transform(coords, 0, coords, 0, 1);
+ return SEG_MOVETO;
}
if (type != OPEN && current == limit)
- return SEG_CLOSE;
+ return SEG_CLOSE;
- if ((current == limit - 1) &&
- (type == PIE) || (type == CHORD))
+ if ((current == limit - 1) && (type == PIE))
{
- if (type == PIE)
- {
- coords[0] = xmid;
- coords[1] = ymid;
- }
- else if (type == CHORD)
- {
- coords[0] = xmid + rx * Math.cos(start);
- coords[1] = ymid - ry * Math.sin(start);
- }
- if (xform != null)
- xform.transform(coords, 0, coords, 0, 1);
- return SEG_LINETO;
+ coords[0] = xmid;
+ coords[1] = ymid;
+ if (xform != null)
+ xform.transform(coords, 0, coords, 0, 1);
+ return SEG_LINETO;
}
// note that this produces a cubic approximation of the arc segment,
// not a true ellipsoid. there's no ellipsoid path segment code,
// unfortunately. the cubic approximation looks about right, though.
-
double kappa = (Math.sqrt(2.0) - 1.0) * (4.0 / 3.0);
double quad = (Math.PI / 2.0);
@@ -717,14 +914,14 @@ public abstract class Arc2D extends RectangularShape
double x0 = xmid + rx * Math.cos(curr_begin);
double y0 = ymid - ry * Math.sin(curr_begin);
-
+
double x1 = xmid + rx * Math.cos(curr_begin + curr_extent);
double y1 = ymid - ry * Math.sin(curr_begin + curr_extent);
- AffineTransform trans = new AffineTransform ();
- double [] cvec = new double[2];
- double len = kappa * portion_of_a_quadrant;
- double angle = curr_begin;
+ AffineTransform trans = new AffineTransform();
+ double[] cvec = new double[2];
+ double len = kappa * portion_of_a_quadrant;
+ double angle = curr_begin;
// in a hypothetical "first quadrant" setting, our first control
// vector would be sticking up, from [1,0] to [1,kappa].
@@ -733,31 +930,29 @@ public abstract class Arc2D extends RectangularShape
// from what one would consider "normal" first quadrant rules, so we
// will *subtract* the y value of this control vector from our first
// point.
-
cvec[0] = 0;
cvec[1] = len;
- trans.scale (rx, ry);
- trans.rotate (angle);
+ trans.scale(rx, ry);
+ trans.rotate(angle);
trans.transform(cvec, 0, cvec, 0, 1);
coords[0] = x0 + cvec[0];
coords[1] = y0 - cvec[1];
// control vector #2 would, ideally, be sticking out and to the
// right, in a first quadrant arc segment. again, subtraction of y.
-
cvec[0] = 0;
cvec[1] = -len;
- trans.rotate (curr_extent);
+ trans.rotate(curr_extent);
trans.transform(cvec, 0, cvec, 0, 1);
coords[2] = x1 + cvec[0];
coords[3] = y1 - cvec[1];
-
+
// end point
coords[4] = x1;
coords[5] = y1;
if (xform != null)
- xform.transform(coords, 0, coords, 0, 3);
+ xform.transform(coords, 0, coords, 0, 3);
return SEG_CUBICTO;
}
@@ -820,8 +1015,8 @@ public abstract class Arc2D extends RectangularShape
* @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
* @throws IllegalArgumentException if type is invalid
*/
- public Double(double x, double y, double w, double h,
- double start, double extent, int type)
+ public Double(double x, double y, double w, double h, double start,
+ double extent, int type)
{
super(type);
this.x = x;
@@ -831,7 +1026,7 @@ public abstract class Arc2D extends RectangularShape
this.start = start;
this.extent = extent;
}
-
+
/**
* Create a new arc with the given dimensions.
*
@@ -935,8 +1130,8 @@ public abstract class Arc2D extends RectangularShape
* @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
* @throws IllegalArgumentException if type is invalid
*/
- public void setArc(double x, double y, double w, double h,
- double start, double extent, int type)
+ public void setArc(double x, double y, double w, double h, double start,
+ double extent, int type)
{
this.x = x;
this.y = y;
@@ -960,7 +1155,7 @@ public abstract class Arc2D extends RectangularShape
/**
* Sets the extent angle of the arc.
*
- * @param start the new extent angle
+ * @param extent the new extent angle
*/
public void setAngleExtent(double extent)
{
@@ -1039,8 +1234,8 @@ public abstract class Arc2D extends RectangularShape
* @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
* @throws IllegalArgumentException if type is invalid
*/
- public Float(float x, float y, float w, float h,
- float start, float extent, int type)
+ public Float(float x, float y, float w, float h, float start,
+ float extent, int type)
{
super(type);
this.x = x;
@@ -1050,7 +1245,7 @@ public abstract class Arc2D extends RectangularShape
this.start = start;
this.extent = extent;
}
-
+
/**
* Create a new arc with the given dimensions.
*
@@ -1069,7 +1264,7 @@ public abstract class Arc2D extends RectangularShape
width = (float) r.getWidth();
height = (float) r.getHeight();
this.start = start;
- this.extent = extent;
+ this.extent = (float) extent;
}
/**
@@ -1154,8 +1349,8 @@ public abstract class Arc2D extends RectangularShape
* @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
* @throws IllegalArgumentException if type is invalid
*/
- public void setArc(double x, double y, double w, double h,
- double start, double extent, int type)
+ public void setArc(double x, double y, double w, double h, double start,
+ double extent, int type)
{
this.x = (float) x;
this.y = (float) y;
@@ -1179,7 +1374,7 @@ public abstract class Arc2D extends RectangularShape
/**
* Sets the extent angle of the arc.
*
- * @param start the new extent angle
+ * @param extent the new extent angle
*/
public void setAngleExtent(double extent)
{
diff --git a/libjava/java/awt/geom/Area.java b/libjava/java/awt/geom/Area.java
index 85bc642cb22..9b1b9d3b109 100644
--- a/libjava/java/awt/geom/Area.java
+++ b/libjava/java/awt/geom/Area.java
@@ -1,5 +1,5 @@
/* Area.java -- represents a shape built by constructive area geometry
- Copyright (C) 2002 Free Software Foundation
+ Copyright (C) 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -35,74 +35,648 @@ 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.awt.geom;
import java.awt.Rectangle;
import java.awt.Shape;
+import java.util.Vector;
+
/**
- * STUBS ONLY
- * XXX Implement and document.
+ * The Area class represents any area for the purpose of
+ * Constructive Area Geometry (CAG) manipulations. CAG manipulations
+ * work as an area-wise form of boolean logic, where the basic operations are:
+ * <P><li>Add (in boolean algebra: A <B>or</B> B)<BR>
+ * <li>Subtract (in boolean algebra: A <B>and</B> (<B>not</B> B) )<BR>
+ * <li>Intersect (in boolean algebra: A <B>and</B> B)<BR>
+ * <li>Exclusive Or <BR>
+ * <img src="doc-files/Area-1.png" width="342" height="302"
+ * alt="Illustration of CAG operations" /><BR>
+ * Above is an illustration of the CAG operations on two ring shapes.<P>
+ *
+ * The contains and intersects() methods are also more accurate than the
+ * specification of #Shape requires.<P>
+ *
+ * Please note that constructing an Area can be slow
+ * (Self-intersection resolving is proportional to the square of
+ * the number of segments).<P>
+ * @see #add(Area)
+ * @see #subtract(Area)
+ * @see #intersect(Area)
+ * @see #exclusiveOr(Area)
+ *
+ * @author Sven de Marothy (sven@physto.se)
+ *
+ * @since 1.2
+ * @status Works, but could be faster and more reliable.
*/
public class Area implements Shape, Cloneable
{
+ /**
+ * General numerical precision
+ */
+ private static final double EPSILON = 1E-11;
+
+ /**
+ * recursive subdivision epsilon - (see getRecursionDepth)
+ */
+ private static final double RS_EPSILON = 1E-13;
+
+ /**
+ * Snap distance - points within this distance are considered equal
+ */
+ private static final double PE_EPSILON = 1E-11;
+
+ /**
+ * Segment vectors containing solid areas and holes
+ */
+ private Vector solids;
+
+ /**
+ * Segment vectors containing solid areas and holes
+ */
+ private Vector holes;
+
+ /**
+ * Vector (temporary) storing curve-curve intersections
+ */
+ private Vector cc_intersections;
+
+ /**
+ * Winding rule WIND_NON_ZERO used, after construction,
+ * this is irrelevant.
+ */
+ private int windingRule;
+
+ /**
+ * Constructs an empty Area
+ */
public Area()
{
+ solids = new Vector();
+ holes = new Vector();
}
+
+ /**
+ * Constructs an Area from any given Shape. <P>
+ *
+ * If the Shape is self-intersecting, the created Area will consist
+ * of non-self-intersecting subpaths, and any inner paths which
+ * are found redundant in accordance with the Shape's winding rule
+ * will not be included.
+ *
+ * @param s the shape (<code>null</code> not permitted).
+ *
+ * @throws NullPointerException if <code>s</code> is <code>null</code>.
+ */
public Area(Shape s)
{
+ this();
+
+ Vector p = makeSegment(s);
+
+ // empty path
+ if (p == null)
+ return;
+
+ // delete empty paths
+ for (int i = 0; i < p.size(); i++)
+ if (((Segment) p.elementAt(i)).getSignedArea() == 0.0)
+ p.remove(i--);
+
+ /*
+ * Resolve self intersecting paths into non-intersecting
+ * solids and holes.
+ * Algorithm is as follows:
+ * 1: Create nodes at all self intersections
+ * 2: Put all segments into a list
+ * 3: Grab a segment, follow it, change direction at each node,
+ * removing segments from the list in the process
+ * 4: Repeat (3) until no segments remain in the list
+ * 5: Remove redundant paths and sort into solids and holes
+ */
+ Vector paths = new Vector();
+ Segment v;
+
+ for (int i = 0; i < p.size(); i++)
+ {
+ Segment path = (Segment) p.elementAt(i);
+ createNodesSelf(path);
+ }
+
+ if (p.size() > 1)
+ {
+ for (int i = 0; i < p.size() - 1; i++)
+ for (int j = i + 1; j < p.size(); j++)
+ {
+ Segment path1 = (Segment) p.elementAt(i);
+ Segment path2 = (Segment) p.elementAt(j);
+ createNodes(path1, path2);
+ }
+ }
+
+ // we have intersecting points.
+ Vector segments = new Vector();
+
+ for (int i = 0; i < p.size(); i++)
+ {
+ Segment path = v = (Segment) p.elementAt(i);
+ do
+ {
+ segments.add(v);
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ paths = weilerAtherton(segments);
+ deleteRedundantPaths(paths);
}
- public void add(Area a)
+
+ /**
+ * Performs an add (union) operation on this area with another Area.<BR>
+ * @param area - the area to be unioned with this one
+ */
+ public void add(Area area)
{
- // XXX Implement.
- throw new Error("not implemented");
+ if (equals(area))
+ return;
+ if (area.isEmpty())
+ return;
+
+ Area B = (Area) area.clone();
+
+ Vector pathA = new Vector();
+ Vector pathB = new Vector();
+ pathA.addAll(solids);
+ pathA.addAll(holes);
+ pathB.addAll(B.solids);
+ pathB.addAll(B.holes);
+
+ int nNodes = 0;
+
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment a = (Segment) pathA.elementAt(i);
+ for (int j = 0; j < pathB.size(); j++)
+ {
+ Segment b = (Segment) pathB.elementAt(j);
+ nNodes += createNodes(a, b);
+ }
+ }
+
+ Vector paths = new Vector();
+ Segment v;
+
+ // we have intersecting points.
+ Vector segments = new Vector();
+
+ // In a union operation, we keep all
+ // segments of A oustide B and all B outside A
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ v = (Segment) pathA.elementAt(i);
+ Segment path = v;
+ do
+ {
+ if (v.isSegmentOutside(area))
+ segments.add(v);
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ for (int i = 0; i < pathB.size(); i++)
+ {
+ v = (Segment) pathB.elementAt(i);
+ Segment path = v;
+ do
+ {
+ if (v.isSegmentOutside(this))
+ segments.add(v);
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ paths = weilerAtherton(segments);
+ deleteRedundantPaths(paths);
}
- public void subtract(Area a)
+
+ /**
+ * Performs a subtraction operation on this Area.<BR>
+ * @param area the area to be subtracted from this area.
+ * @throws NullPointerException if <code>area</code> is <code>null</code>.
+ */
+ public void subtract(Area area)
{
- // XXX Implement.
- throw new Error("not implemented");
+ if (isEmpty() || area.isEmpty())
+ return;
+
+ if (equals(area))
+ {
+ reset();
+ return;
+ }
+
+ Vector pathA = new Vector();
+ Area B = (Area) area.clone();
+ pathA.addAll(solids);
+ pathA.addAll(holes);
+
+ // reverse the directions of B paths.
+ setDirection(B.holes, true);
+ setDirection(B.solids, false);
+
+ Vector pathB = new Vector();
+ pathB.addAll(B.solids);
+ pathB.addAll(B.holes);
+
+ int nNodes = 0;
+
+ // create nodes
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment a = (Segment) pathA.elementAt(i);
+ for (int j = 0; j < pathB.size(); j++)
+ {
+ Segment b = (Segment) pathB.elementAt(j);
+ nNodes += createNodes(a, b);
+ }
+ }
+
+ Vector paths = new Vector();
+
+ // we have intersecting points.
+ Vector segments = new Vector();
+
+ // In a subtraction operation, we keep all
+ // segments of A oustide B and all B within A
+ // We outsideness-test only one segment in each path
+ // and the segments before and after any node
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment v = (Segment) pathA.elementAt(i);
+ Segment path = v;
+ if (v.isSegmentOutside(area) && v.node == null)
+ segments.add(v);
+ boolean node = false;
+ do
+ {
+ if ((v.node != null || node))
+ {
+ node = (v.node != null);
+ if (v.isSegmentOutside(area))
+ segments.add(v);
+ }
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ for (int i = 0; i < pathB.size(); i++)
+ {
+ Segment v = (Segment) pathB.elementAt(i);
+ Segment path = v;
+ if (! v.isSegmentOutside(this) && v.node == null)
+ segments.add(v);
+ v = v.next;
+ boolean node = false;
+ do
+ {
+ if ((v.node != null || node))
+ {
+ node = (v.node != null);
+ if (! v.isSegmentOutside(this))
+ segments.add(v);
+ }
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ paths = weilerAtherton(segments);
+ deleteRedundantPaths(paths);
}
- public void intersect(Area a)
+
+ /**
+ * Performs an intersection operation on this Area.<BR>
+ * @param area - the area to be intersected with this area.
+ * @throws NullPointerException if <code>area</code> is <code>null</code>.
+ */
+ public void intersect(Area area)
{
- // XXX Implement.
- throw new Error("not implemented");
+ if (isEmpty() || area.isEmpty())
+ {
+ reset();
+ return;
+ }
+ if (equals(area))
+ return;
+
+ Vector pathA = new Vector();
+ Area B = (Area) area.clone();
+ pathA.addAll(solids);
+ pathA.addAll(holes);
+
+ Vector pathB = new Vector();
+ pathB.addAll(B.solids);
+ pathB.addAll(B.holes);
+
+ int nNodes = 0;
+
+ // create nodes
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment a = (Segment) pathA.elementAt(i);
+ for (int j = 0; j < pathB.size(); j++)
+ {
+ Segment b = (Segment) pathB.elementAt(j);
+ nNodes += createNodes(a, b);
+ }
+ }
+
+ Vector paths = new Vector();
+
+ // we have intersecting points.
+ Vector segments = new Vector();
+
+ // In an intersection operation, we keep all
+ // segments of A within B and all B within A
+ // (The rest must be redundant)
+ // We outsideness-test only one segment in each path
+ // and the segments before and after any node
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment v = (Segment) pathA.elementAt(i);
+ Segment path = v;
+ if (! v.isSegmentOutside(area) && v.node == null)
+ segments.add(v);
+ boolean node = false;
+ do
+ {
+ if ((v.node != null || node))
+ {
+ node = (v.node != null);
+ if (! v.isSegmentOutside(area))
+ segments.add(v);
+ }
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ for (int i = 0; i < pathB.size(); i++)
+ {
+ Segment v = (Segment) pathB.elementAt(i);
+ Segment path = v;
+ if (! v.isSegmentOutside(this) && v.node == null)
+ segments.add(v);
+ v = v.next;
+ boolean node = false;
+ do
+ {
+ if ((v.node != null || node))
+ {
+ node = (v.node != null);
+ if (! v.isSegmentOutside(this))
+ segments.add(v);
+ }
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ paths = weilerAtherton(segments);
+ deleteRedundantPaths(paths);
}
- public void exclusiveOr(Area a)
+
+ /**
+ * Performs an exclusive-or operation on this Area.<BR>
+ * @param area - the area to be XORed with this area.
+ * @throws NullPointerException if <code>area</code> is <code>null</code>.
+ */
+ public void exclusiveOr(Area area)
{
- // XXX Implement.
- throw new Error("not implemented");
+ if (area.isEmpty())
+ return;
+
+ if (isEmpty())
+ {
+ Area B = (Area) area.clone();
+ solids = B.solids;
+ holes = B.holes;
+ return;
+ }
+ if (equals(area))
+ {
+ reset();
+ return;
+ }
+
+ Vector pathA = new Vector();
+
+ Area B = (Area) area.clone();
+ Vector pathB = new Vector();
+ pathA.addAll(solids);
+ pathA.addAll(holes);
+
+ // reverse the directions of B paths.
+ setDirection(B.holes, true);
+ setDirection(B.solids, false);
+ pathB.addAll(B.solids);
+ pathB.addAll(B.holes);
+
+ int nNodes = 0;
+
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ Segment a = (Segment) pathA.elementAt(i);
+ for (int j = 0; j < pathB.size(); j++)
+ {
+ Segment b = (Segment) pathB.elementAt(j);
+ nNodes += createNodes(a, b);
+ }
+ }
+
+ Vector paths = new Vector();
+ Segment v;
+
+ // we have intersecting points.
+ Vector segments = new Vector();
+
+ // In an XOR operation, we operate on all segments
+ for (int i = 0; i < pathA.size(); i++)
+ {
+ v = (Segment) pathA.elementAt(i);
+ Segment path = v;
+ do
+ {
+ segments.add(v);
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ for (int i = 0; i < pathB.size(); i++)
+ {
+ v = (Segment) pathB.elementAt(i);
+ Segment path = v;
+ do
+ {
+ segments.add(v);
+ v = v.next;
+ }
+ while (v != path);
+ }
+
+ paths = weilerAtherton(segments);
+ deleteRedundantPaths(paths);
}
+
+ /**
+ * Clears the Area object, creating an empty area.
+ */
public void reset()
{
- // XXX Implement.
- throw new Error("not implemented");
+ solids = new Vector();
+ holes = new Vector();
}
+
+ /**
+ * Returns whether this area encloses any area.
+ * @return true if the object encloses any area.
+ */
public boolean isEmpty()
{
- // XXX Implement.
- throw new Error("not implemented");
+ if (solids.size() == 0)
+ return true;
+
+ double totalArea = 0;
+ for (int i = 0; i < solids.size(); i++)
+ totalArea += Math.abs(((Segment) solids.elementAt(i)).getSignedArea());
+ for (int i = 0; i < holes.size(); i++)
+ totalArea -= Math.abs(((Segment) holes.elementAt(i)).getSignedArea());
+ if (totalArea <= EPSILON)
+ return true;
+
+ return false;
}
+
+ /**
+ * Determines whether the Area consists entirely of line segments
+ * @return true if the Area lines-only, false otherwise
+ */
public boolean isPolygonal()
{
- // XXX Implement.
- throw new Error("not implemented");
+ for (int i = 0; i < holes.size(); i++)
+ if (! ((Segment) holes.elementAt(i)).isPolygonal())
+ return false;
+ for (int i = 0; i < solids.size(); i++)
+ if (! ((Segment) solids.elementAt(i)).isPolygonal())
+ return false;
+ return true;
}
+
+ /**
+ * Determines if the Area is rectangular.<P>
+ *
+ * This is strictly qualified. An area is considered rectangular if:<BR>
+ * <li>It consists of a single polygonal path.<BR>
+ * <li>It is oriented parallel/perpendicular to the xy axis<BR>
+ * <li>It must be exactly rectangular, i.e. small errors induced by
+ * transformations may cause a false result, although the area is
+ * visibly rectangular.<P>
+ * @return true if the above criteria are met, false otherwise
+ */
public boolean isRectangular()
{
- // XXX Implement.
- throw new Error("not implemented");
+ if (isEmpty())
+ return true;
+
+ if (holes.size() != 0 || solids.size() != 1)
+ return false;
+
+ Segment path = (Segment) solids.elementAt(0);
+ if (! path.isPolygonal())
+ return false;
+
+ int nCorners = 0;
+ Segment s = path;
+ do
+ {
+ Segment s2 = s.next;
+ double d1 = (s.P2.getX() - s.P1.getX())*(s2.P2.getX() - s2.P1.getX())/
+ ((s.P1.distance(s.P2)) * (s2.P1.distance(s2.P2)));
+ double d2 = (s.P2.getY() - s.P1.getY())*(s2.P2.getY() - s2.P1.getY())/
+ ((s.P1.distance(s.P2)) * (s2.P1.distance(s2.P2)));
+ double dotproduct = d1 + d2;
+
+ // For some reason, only rectangles on the XY axis count.
+ if (d1 != 0 && d2 != 0)
+ return false;
+
+ if (Math.abs(dotproduct) == 0) // 90 degree angle
+ nCorners++;
+ else if ((Math.abs(1.0 - dotproduct) > 0)) // 0 degree angle?
+ return false; // if not, return false
+
+ s = s.next;
+ }
+ while (s != path);
+
+ return nCorners == 4;
}
+
+ /**
+ * Returns whether the Area consists of more than one simple
+ * (non self-intersecting) subpath.
+ *
+ * @return true if the Area consists of none or one simple subpath,
+ * false otherwise.
+ */
public boolean isSingular()
{
- // XXX Implement.
- throw new Error("not implemented");
+ return (holes.size() == 0 && solids.size() <= 1);
}
+
+ /**
+ * Returns the bounding box of the Area.<P> Unlike the CubicCurve2D and
+ * QuadraticCurve2D classes, this method will return the tightest possible
+ * bounding box, evaluating the extreme points of each curved segment.<P>
+ * @return the bounding box
+ */
public Rectangle2D getBounds2D()
{
- // XXX Implement.
- throw new Error("not implemented");
+ if (solids.size() == 0)
+ return new Rectangle2D.Double(0.0, 0.0, 0.0, 0.0);
+
+ double xmin;
+ double xmax;
+ double ymin;
+ double ymax;
+ xmin = xmax = ((Segment) solids.elementAt(0)).P1.getX();
+ ymin = ymax = ((Segment) solids.elementAt(0)).P1.getY();
+
+ for (int path = 0; path < solids.size(); path++)
+ {
+ Rectangle2D r = ((Segment) solids.elementAt(path)).getPathBounds();
+ xmin = Math.min(r.getMinX(), xmin);
+ ymin = Math.min(r.getMinY(), ymin);
+ xmax = Math.max(r.getMaxX(), xmax);
+ ymax = Math.max(r.getMaxY(), ymax);
+ }
+
+ return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
}
+
+ /**
+ * Returns the bounds of this object in Rectangle format.
+ * Please note that this may lead to loss of precision.
+ *
+ * @return The bounds.
+ * @see #getBounds2D()
+ */
public Rectangle getBounds()
{
return getBounds2D().getBounds();
@@ -118,66 +692,2618 @@ public class Area implements Shape, Cloneable
{
try
{
- return super.clone();
+ Area clone = new Area();
+ for (int i = 0; i < solids.size(); i++)
+ clone.solids.add(((Segment) solids.elementAt(i)).cloneSegmentList());
+ for (int i = 0; i < holes.size(); i++)
+ clone.holes.add(((Segment) holes.elementAt(i)).cloneSegmentList());
+ return clone;
}
catch (CloneNotSupportedException e)
{
- throw (Error) new InternalError().initCause(e); // Impossible
+ throw (Error) new InternalError().initCause(e); // Impossible
}
}
- public boolean equals(Area a)
+ /**
+ * Compares two Areas.
+ *
+ * @param area the area to compare against this area (<code>null</code>
+ * permitted).
+ * @return <code>true</code> if the areas are equal, and <code>false</code>
+ * otherwise.
+ */
+ public boolean equals(Area area)
{
- // XXX Implement.
- throw new Error("not implemented");
+ if (area == null)
+ return false;
+
+ if (! getBounds2D().equals(area.getBounds2D()))
+ return false;
+
+ if (solids.size() != area.solids.size()
+ || holes.size() != area.holes.size())
+ return false;
+
+ Vector pathA = new Vector();
+ pathA.addAll(solids);
+ pathA.addAll(holes);
+ Vector pathB = new Vector();
+ pathB.addAll(area.solids);
+ pathB.addAll(area.holes);
+
+ int nPaths = pathA.size();
+ boolean[][] match = new boolean[2][nPaths];
+
+ for (int i = 0; i < nPaths; i++)
+ {
+ for (int j = 0; j < nPaths; j++)
+ {
+ Segment p1 = (Segment) pathA.elementAt(i);
+ Segment p2 = (Segment) pathB.elementAt(j);
+ if (! match[0][i] && ! match[1][j])
+ if (p1.pathEquals(p2))
+ match[0][i] = match[1][j] = true;
+ }
+ }
+
+ boolean result = true;
+ for (int i = 0; i < nPaths; i++)
+ result = result && match[0][i] && match[1][i];
+ return result;
}
+ /**
+ * Transforms this area by the AffineTransform at.
+ *
+ * @param at the transform.
+ */
public void transform(AffineTransform at)
{
- // XXX Implement.
- throw new Error("not implemented");
+ for (int i = 0; i < solids.size(); i++)
+ ((Segment) solids.elementAt(i)).transformSegmentList(at);
+ for (int i = 0; i < holes.size(); i++)
+ ((Segment) holes.elementAt(i)).transformSegmentList(at);
+
+ // Note that the orientation is not invariant under inversion
+ if ((at.getType() & AffineTransform.TYPE_FLIP) != 0)
+ {
+ setDirection(holes, false);
+ setDirection(solids, true);
+ }
}
+
+ /**
+ * Returns a new Area equal to this one, transformed
+ * by the AffineTransform at.
+ * @param at the transform.
+ * @return the transformed area
+ * @throws NullPointerException if <code>at</code> is <code>null</code>.
+ */
public Area createTransformedArea(AffineTransform at)
{
Area a = (Area) clone();
a.transform(at);
return a;
}
+
+ /**
+ * Determines if the point (x,y) is contained within this Area.
+ *
+ * @param x the x-coordinate of the point.
+ * @param y the y-coordinate of the point.
+ * @return true if the point is contained, false otherwise.
+ */
public boolean contains(double x, double y)
{
- // XXX Implement.
- throw new Error("not implemented");
+ int n = 0;
+ for (int i = 0; i < solids.size(); i++)
+ if (((Segment) solids.elementAt(i)).contains(x, y))
+ n++;
+
+ for (int i = 0; i < holes.size(); i++)
+ if (((Segment) holes.elementAt(i)).contains(x, y))
+ n--;
+
+ return (n != 0);
}
+
+ /**
+ * Determines if the Point2D p is contained within this Area.
+ *
+ * @param p the point.
+ * @return <code>true</code> if the point is contained, <code>false</code>
+ * otherwise.
+ * @throws NullPointerException if <code>p</code> is <code>null</code>.
+ */
public boolean contains(Point2D p)
{
return contains(p.getX(), p.getY());
}
+
+ /**
+ * Determines if the rectangle specified by (x,y) as the upper-left
+ * and with width w and height h is completely contained within this Area,
+ * returns false otherwise.<P>
+ *
+ * This method should always produce the correct results, unlike for other
+ * classes in geom.
+ *
+ * @param x the x-coordinate of the rectangle.
+ * @param y the y-coordinate of the rectangle.
+ * @param w the width of the the rectangle.
+ * @param h the height of the rectangle.
+ * @return <code>true</code> if the rectangle is considered contained
+ */
public boolean contains(double x, double y, double w, double h)
{
- // XXX Implement.
- throw new Error("not implemented");
+ LineSegment[] l = new LineSegment[4];
+ l[0] = new LineSegment(x, y, x + w, y);
+ l[1] = new LineSegment(x, y + h, x + w, y + h);
+ l[2] = new LineSegment(x, y, x, y + h);
+ l[3] = new LineSegment(x + w, y, x + w, y + h);
+
+ // Since every segment in the area must a contour
+ // between inside/outside segments, ANY intersection
+ // will mean the rectangle is not entirely contained.
+ for (int i = 0; i < 4; i++)
+ {
+ for (int path = 0; path < solids.size(); path++)
+ {
+ Segment v;
+ Segment start;
+ start = v = (Segment) solids.elementAt(path);
+ do
+ {
+ if (l[i].hasIntersections(v))
+ return false;
+ v = v.next;
+ }
+ while (v != start);
+ }
+ for (int path = 0; path < holes.size(); path++)
+ {
+ Segment v;
+ Segment start;
+ start = v = (Segment) holes.elementAt(path);
+ do
+ {
+ if (l[i].hasIntersections(v))
+ return false;
+ v = v.next;
+ }
+ while (v != start);
+ }
+ }
+
+ // Is any point inside?
+ if (! contains(x, y))
+ return false;
+
+ // Final hoop: Is the rectangle non-intersecting and inside,
+ // but encloses a hole?
+ Rectangle2D r = new Rectangle2D.Double(x, y, w, h);
+ for (int path = 0; path < holes.size(); path++)
+ if (! ((Segment) holes.elementAt(path)).isSegmentOutside(r))
+ return false;
+
+ return true;
}
+
+ /**
+ * Determines if the Rectangle2D specified by r is completely contained
+ * within this Area, returns false otherwise.<P>
+ *
+ * This method should always produce the correct results, unlike for other
+ * classes in geom.
+ *
+ * @param r the rectangle.
+ * @return <code>true</code> if the rectangle is considered contained
+ *
+ * @throws NullPointerException if <code>r</code> is <code>null</code>.
+ */
public boolean contains(Rectangle2D r)
{
return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
+ /**
+ * Determines if the rectangle specified by (x,y) as the upper-left
+ * and with width w and height h intersects any part of this Area.
+ *
+ * @param x the x-coordinate for the rectangle.
+ * @param y the y-coordinate for the rectangle.
+ * @param w the width of the rectangle.
+ * @param h the height of the rectangle.
+ * @return <code>true</code> if the rectangle intersects the area,
+ * <code>false</code> otherwise.
+ */
public boolean intersects(double x, double y, double w, double h)
{
- // XXX Implement.
- throw new Error("not implemented");
+ if (solids.size() == 0)
+ return false;
+
+ LineSegment[] l = new LineSegment[4];
+ l[0] = new LineSegment(x, y, x + w, y);
+ l[1] = new LineSegment(x, y + h, x + w, y + h);
+ l[2] = new LineSegment(x, y, x, y + h);
+ l[3] = new LineSegment(x + w, y, x + w, y + h);
+
+ // Return true on any intersection
+ for (int i = 0; i < 4; i++)
+ {
+ for (int path = 0; path < solids.size(); path++)
+ {
+ Segment v;
+ Segment start;
+ start = v = (Segment) solids.elementAt(path);
+ do
+ {
+ if (l[i].hasIntersections(v))
+ return true;
+ v = v.next;
+ }
+ while (v != start);
+ }
+ for (int path = 0; path < holes.size(); path++)
+ {
+ Segment v;
+ Segment start;
+ start = v = (Segment) holes.elementAt(path);
+ do
+ {
+ if (l[i].hasIntersections(v))
+ return true;
+ v = v.next;
+ }
+ while (v != start);
+ }
+ }
+
+ // Non-intersecting, Is any point inside?
+ if (contains(x + w * 0.5, y + h * 0.5))
+ return true;
+
+ // What if the rectangle encloses the whole shape?
+ Point2D p = ((Segment) solids.elementAt(0)).getMidPoint();
+ if ((new Rectangle2D.Double(x, y, w, h)).contains(p))
+ return true;
+ return false;
}
+
+ /**
+ * Determines if the Rectangle2D specified by r intersects any
+ * part of this Area.
+ * @param r the rectangle to test intersection with (<code>null</code>
+ * not permitted).
+ * @return <code>true</code> if the rectangle intersects the area,
+ * <code>false</code> otherwise.
+ * @throws NullPointerException if <code>r</code> is <code>null</code>.
+ */
public boolean intersects(Rectangle2D r)
{
return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
+
+ /**
+ * Returns a PathIterator object defining the contour of this Area,
+ * transformed by at.
+ *
+ * @param at the transform.
+ * @return A path iterator.
+ */
public PathIterator getPathIterator(AffineTransform at)
{
- // XXX Implement.
- throw new Error("not implemented");
+ return (new AreaIterator(at));
}
+
+ /**
+ * Returns a flattened PathIterator object defining the contour of this
+ * Area, transformed by at and with a defined flatness.
+ *
+ * @param at the transform.
+ * @param flatness the flatness.
+ * @return A path iterator.
+ */
public PathIterator getPathIterator(AffineTransform at, double flatness)
{
return new FlatteningPathIterator(getPathIterator(at), flatness);
}
+
+ //---------------------------------------------------------------------
+ // Non-public methods and classes
+
+ /**
+ * Private pathiterator object.
+ */
+ private class AreaIterator implements PathIterator
+ {
+ private Vector segments;
+ private int index;
+ private AffineTransform at;
+
+ // Simple compound type for segments
+ class IteratorSegment
+ {
+ int type;
+ double[] coords;
+
+ IteratorSegment()
+ {
+ coords = new double[6];
+ }
+ }
+
+ /**
+ * The contructor here does most of the work,
+ * creates a vector of IteratorSegments, which can
+ * readily be returned
+ */
+ public AreaIterator(AffineTransform at)
+ {
+ this.at = at;
+ index = 0;
+ segments = new Vector();
+ Vector allpaths = new Vector();
+ allpaths.addAll(solids);
+ allpaths.addAll(holes);
+
+ for (int i = 0; i < allpaths.size(); i++)
+ {
+ Segment v = (Segment) allpaths.elementAt(i);
+ Segment start = v;
+
+ IteratorSegment is = new IteratorSegment();
+ is.type = SEG_MOVETO;
+ is.coords[0] = start.P1.getX();
+ is.coords[1] = start.P1.getY();
+ segments.add(is);
+
+ do
+ {
+ is = new IteratorSegment();
+ is.type = v.pathIteratorFormat(is.coords);
+ segments.add(is);
+ v = v.next;
+ }
+ while (v != start);
+
+ is = new IteratorSegment();
+ is.type = SEG_CLOSE;
+ segments.add(is);
+ }
+ }
+
+ public int currentSegment(double[] coords)
+ {
+ IteratorSegment s = (IteratorSegment) segments.elementAt(index);
+ if (at != null)
+ at.transform(s.coords, 0, coords, 0, 3);
+ else
+ for (int i = 0; i < 6; i++)
+ coords[i] = s.coords[i];
+ return (s.type);
+ }
+
+ public int currentSegment(float[] coords)
+ {
+ IteratorSegment s = (IteratorSegment) segments.elementAt(index);
+ double[] d = new double[6];
+ if (at != null)
+ {
+ at.transform(s.coords, 0, d, 0, 3);
+ for (int i = 0; i < 6; i++)
+ coords[i] = (float) d[i];
+ }
+ else
+ for (int i = 0; i < 6; i++)
+ coords[i] = (float) s.coords[i];
+ return (s.type);
+ }
+
+ // Note that the winding rule should not matter here,
+ // EVEN_ODD is chosen because it renders faster.
+ public int getWindingRule()
+ {
+ return (PathIterator.WIND_EVEN_ODD);
+ }
+
+ public boolean isDone()
+ {
+ return (index >= segments.size());
+ }
+
+ public void next()
+ {
+ index++;
+ }
+ }
+
+ /**
+ * Performs the fundamental task of the Weiler-Atherton algorithm,
+ * traverse a list of segments, for each segment:
+ * Follow it, removing segments from the list and switching paths
+ * at each node. Do so until the starting segment is reached.
+ *
+ * Returns a Vector of the resulting paths.
+ */
+ private Vector weilerAtherton(Vector segments)
+ {
+ Vector paths = new Vector();
+ while (segments.size() > 0)
+ {
+ // Iterate over the path
+ Segment start = (Segment) segments.elementAt(0);
+ Segment s = start;
+ do
+ {
+ segments.remove(s);
+ if (s.node != null)
+ { // switch over
+ s.next = s.node;
+ s.node = null;
+ }
+ s = s.next; // continue
+ }
+ while (s != start);
+
+ paths.add(start);
+ }
+ return paths;
+ }
+
+ /**
+ * A small wrapper class to store intersection points
+ */
+ private class Intersection
+ {
+ Point2D p; // the 2D point of intersection
+ double ta; // the parametric value on a
+ double tb; // the parametric value on b
+ Segment seg; // segment placeholder for node setting
+
+ public Intersection(Point2D p, double ta, double tb)
+ {
+ this.p = p;
+ this.ta = ta;
+ this.tb = tb;
+ }
+ }
+
+ /**
+ * Returns the recursion depth necessary to approximate the
+ * curve by line segments within the error RS_EPSILON.
+ *
+ * This is done with Wang's formula:
+ * L0 = max{0<=i<=N-2}(|xi - 2xi+1 + xi+2|,|yi - 2yi+1 + yi+2|)
+ * r0 = log4(sqrt(2)*N*(N-1)*L0/8e)
+ * Where e is the maximum distance error (RS_EPSILON)
+ */
+ private int getRecursionDepth(CubicSegment curve)
+ {
+ double x0 = curve.P1.getX();
+ double y0 = curve.P1.getY();
+
+ double x1 = curve.cp1.getX();
+ double y1 = curve.cp1.getY();
+
+ double x2 = curve.cp2.getX();
+ double y2 = curve.cp2.getY();
+
+ double x3 = curve.P2.getX();
+ double y3 = curve.P2.getY();
+
+ double L0 = Math.max(Math.max(Math.abs(x0 - 2 * x1 + x2),
+ Math.abs(x1 - 2 * x2 + x3)),
+ Math.max(Math.abs(y0 - 2 * y1 + y2),
+ Math.abs(y1 - 2 * y2 + y3)));
+
+ double f = Math.sqrt(2) * 6.0 * L0 / (8.0 * RS_EPSILON);
+
+ int r0 = (int) Math.ceil(Math.log(f) / Math.log(4.0));
+ return (r0);
+ }
+
+ /**
+ * Performs recursive subdivision:
+ * @param c1 - curve 1
+ * @param c2 - curve 2
+ * @param depth1 - recursion depth of curve 1
+ * @param depth2 - recursion depth of curve 2
+ * @param t1 - global parametric value of the first curve's starting point
+ * @param t2 - global parametric value of the second curve's starting point
+ * @param w1 - global parametric length of curve 1
+ * @param c1 - global parametric length of curve 2
+ *
+ * The final four parameters are for keeping track of the parametric
+ * value of the curve. For a full curve t = 0, w = 1, w is halved with
+ * each subdivision.
+ */
+ private void recursiveSubdivide(CubicCurve2D c1, CubicCurve2D c2,
+ int depth1, int depth2, double t1,
+ double t2, double w1, double w2)
+ {
+ boolean flat1 = depth1 <= 0;
+ boolean flat2 = depth2 <= 0;
+
+ if (flat1 && flat2)
+ {
+ double xlk = c1.getP2().getX() - c1.getP1().getX();
+ double ylk = c1.getP2().getY() - c1.getP1().getY();
+
+ double xnm = c2.getP2().getX() - c2.getP1().getX();
+ double ynm = c2.getP2().getY() - c2.getP1().getY();
+
+ double xmk = c2.getP1().getX() - c1.getP1().getX();
+ double ymk = c2.getP1().getY() - c1.getP1().getY();
+ double det = xnm * ylk - ynm * xlk;
+
+ if (det + 1.0 == 1.0)
+ return;
+
+ double detinv = 1.0 / det;
+ double s = (xnm * ymk - ynm * xmk) * detinv;
+ double t = (xlk * ymk - ylk * xmk) * detinv;
+ if ((s < 0.0) || (s > 1.0) || (t < 0.0) || (t > 1.0))
+ return;
+
+ double[] temp = new double[2];
+ temp[0] = t1 + s * w1;
+ temp[1] = t2 + t * w1;
+ cc_intersections.add(temp);
+ return;
+ }
+
+ CubicCurve2D.Double c11 = new CubicCurve2D.Double();
+ CubicCurve2D.Double c12 = new CubicCurve2D.Double();
+ CubicCurve2D.Double c21 = new CubicCurve2D.Double();
+ CubicCurve2D.Double c22 = new CubicCurve2D.Double();
+
+ if (! flat1 && ! flat2)
+ {
+ depth1--;
+ depth2--;
+ w1 = w1 * 0.5;
+ w2 = w2 * 0.5;
+ c1.subdivide(c11, c12);
+ c2.subdivide(c21, c22);
+ if (c11.getBounds2D().intersects(c21.getBounds2D()))
+ recursiveSubdivide(c11, c21, depth1, depth2, t1, t2, w1, w2);
+ if (c11.getBounds2D().intersects(c22.getBounds2D()))
+ recursiveSubdivide(c11, c22, depth1, depth2, t1, t2 + w2, w1, w2);
+ if (c12.getBounds2D().intersects(c21.getBounds2D()))
+ recursiveSubdivide(c12, c21, depth1, depth2, t1 + w1, t2, w1, w2);
+ if (c12.getBounds2D().intersects(c22.getBounds2D()))
+ recursiveSubdivide(c12, c22, depth1, depth2, t1 + w1, t2 + w2, w1, w2);
+ return;
+ }
+
+ if (! flat1)
+ {
+ depth1--;
+ c1.subdivide(c11, c12);
+ w1 = w1 * 0.5;
+ if (c11.getBounds2D().intersects(c2.getBounds2D()))
+ recursiveSubdivide(c11, c2, depth1, depth2, t1, t2, w1, w2);
+ if (c12.getBounds2D().intersects(c2.getBounds2D()))
+ recursiveSubdivide(c12, c2, depth1, depth2, t1 + w1, t2, w1, w2);
+ return;
+ }
+
+ depth2--;
+ c2.subdivide(c21, c22);
+ w2 = w2 * 0.5;
+ if (c1.getBounds2D().intersects(c21.getBounds2D()))
+ recursiveSubdivide(c1, c21, depth1, depth2, t1, t2, w1, w2);
+ if (c1.getBounds2D().intersects(c22.getBounds2D()))
+ recursiveSubdivide(c1, c22, depth1, depth2, t1, t2 + w2, w1, w2);
+ }
+
+ /**
+ * Returns a set of interesections between two Cubic segments
+ * Or null if no intersections were found.
+ *
+ * The method used to find the intersection is recursive midpoint
+ * subdivision. Outline description:
+ *
+ * 1) Check if the bounding boxes of the curves intersect,
+ * 2) If so, divide the curves in the middle and test the bounding
+ * boxes again,
+ * 3) Repeat until a maximum recursion depth has been reached, where
+ * the intersecting curves can be approximated by line segments.
+ *
+ * This is a reasonably accurate method, although the recursion depth
+ * is typically around 20, the bounding-box tests allow for significant
+ * pruning of the subdivision tree.
+ */
+ private Intersection[] cubicCubicIntersect(CubicSegment curve1,
+ CubicSegment curve2)
+ {
+ Rectangle2D r1 = curve1.getBounds();
+ Rectangle2D r2 = curve2.getBounds();
+
+ if (! r1.intersects(r2))
+ return null;
+
+ cc_intersections = new Vector();
+ recursiveSubdivide(curve1.getCubicCurve2D(), curve2.getCubicCurve2D(),
+ getRecursionDepth(curve1), getRecursionDepth(curve2),
+ 0.0, 0.0, 1.0, 1.0);
+
+ if (cc_intersections.size() == 0)
+ return null;
+
+ Intersection[] results = new Intersection[cc_intersections.size()];
+ for (int i = 0; i < cc_intersections.size(); i++)
+ {
+ double[] temp = (double[]) cc_intersections.elementAt(i);
+ results[i] = new Intersection(curve1.evaluatePoint(temp[0]), temp[0],
+ temp[1]);
+ }
+ cc_intersections = null;
+ return (results);
+ }
+
+ /**
+ * Returns the intersections between a line and a quadratic bezier
+ * Or null if no intersections are found1
+ * This is done through combining the line's equation with the
+ * parametric form of the Bezier and solving the resulting quadratic.
+ */
+ private Intersection[] lineQuadIntersect(LineSegment l, QuadSegment c)
+ {
+ double[] y = new double[3];
+ double[] x = new double[3];
+ double[] r = new double[3];
+ int nRoots;
+ double x0 = c.P1.getX();
+ double y0 = c.P1.getY();
+ double x1 = c.cp.getX();
+ double y1 = c.cp.getY();
+ double x2 = c.P2.getX();
+ double y2 = c.P2.getY();
+
+ double lx0 = l.P1.getX();
+ double ly0 = l.P1.getY();
+ double lx1 = l.P2.getX();
+ double ly1 = l.P2.getY();
+ double dx = lx1 - lx0;
+ double dy = ly1 - ly0;
+
+ // form r(t) = y(t) - x(t) for the bezier
+ y[0] = y0;
+ y[1] = 2 * (y1 - y0);
+ y[2] = (y2 - 2 * y1 + y0);
+
+ x[0] = x0;
+ x[1] = 2 * (x1 - x0);
+ x[2] = (x2 - 2 * x1 + x0);
+
+ // a point, not a line
+ if (dy == 0 && dx == 0)
+ return null;
+
+ // line on y axis
+ if (dx == 0 || (dy / dx) > 1.0)
+ {
+ double k = dx / dy;
+ x[0] -= lx0;
+ y[0] -= ly0;
+ y[0] *= k;
+ y[1] *= k;
+ y[2] *= k;
+ }
+ else
+ {
+ double k = dy / dx;
+ x[0] -= lx0;
+ y[0] -= ly0;
+ x[0] *= k;
+ x[1] *= k;
+ x[2] *= k;
+ }
+
+ for (int i = 0; i < 3; i++)
+ r[i] = y[i] - x[i];
+
+ if ((nRoots = QuadCurve2D.solveQuadratic(r)) > 0)
+ {
+ Intersection[] temp = new Intersection[nRoots];
+ int intersections = 0;
+ for (int i = 0; i < nRoots; i++)
+ {
+ double t = r[i];
+ if (t >= 0.0 && t <= 1.0)
+ {
+ Point2D p = c.evaluatePoint(t);
+
+ // if the line is on an axis, snap the point to that axis.
+ if (dx == 0)
+ p.setLocation(lx0, p.getY());
+ if (dy == 0)
+ p.setLocation(p.getX(), ly0);
+
+ if (p.getX() <= Math.max(lx0, lx1)
+ && p.getX() >= Math.min(lx0, lx1)
+ && p.getY() <= Math.max(ly0, ly1)
+ && p.getY() >= Math.min(ly0, ly1))
+ {
+ double lineparameter = p.distance(l.P1) / l.P2.distance(l.P1);
+ temp[i] = new Intersection(p, lineparameter, t);
+ intersections++;
+ }
+ }
+ else
+ temp[i] = null;
+ }
+ if (intersections == 0)
+ return null;
+
+ Intersection[] rValues = new Intersection[intersections];
+
+ for (int i = 0; i < nRoots; i++)
+ if (temp[i] != null)
+ rValues[--intersections] = temp[i];
+ return (rValues);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the intersections between a line and a cubic segment
+ * This is done through combining the line's equation with the
+ * parametric form of the Bezier and solving the resulting quadratic.
+ */
+ private Intersection[] lineCubicIntersect(LineSegment l, CubicSegment c)
+ {
+ double[] y = new double[4];
+ double[] x = new double[4];
+ double[] r = new double[4];
+ int nRoots;
+ double x0 = c.P1.getX();
+ double y0 = c.P1.getY();
+ double x1 = c.cp1.getX();
+ double y1 = c.cp1.getY();
+ double x2 = c.cp2.getX();
+ double y2 = c.cp2.getY();
+ double x3 = c.P2.getX();
+ double y3 = c.P2.getY();
+
+ double lx0 = l.P1.getX();
+ double ly0 = l.P1.getY();
+ double lx1 = l.P2.getX();
+ double ly1 = l.P2.getY();
+ double dx = lx1 - lx0;
+ double dy = ly1 - ly0;
+
+ // form r(t) = y(t) - x(t) for the bezier
+ y[0] = y0;
+ y[1] = 3 * (y1 - y0);
+ y[2] = 3 * (y2 + y0 - 2 * y1);
+ y[3] = y3 - 3 * y2 + 3 * y1 - y0;
+
+ x[0] = x0;
+ x[1] = 3 * (x1 - x0);
+ x[2] = 3 * (x2 + x0 - 2 * x1);
+ x[3] = x3 - 3 * x2 + 3 * x1 - x0;
+
+ // a point, not a line
+ if (dy == 0 && dx == 0)
+ return null;
+
+ // line on y axis
+ if (dx == 0 || (dy / dx) > 1.0)
+ {
+ double k = dx / dy;
+ x[0] -= lx0;
+ y[0] -= ly0;
+ y[0] *= k;
+ y[1] *= k;
+ y[2] *= k;
+ y[3] *= k;
+ }
+ else
+ {
+ double k = dy / dx;
+ x[0] -= lx0;
+ y[0] -= ly0;
+ x[0] *= k;
+ x[1] *= k;
+ x[2] *= k;
+ x[3] *= k;
+ }
+ for (int i = 0; i < 4; i++)
+ r[i] = y[i] - x[i];
+
+ if ((nRoots = CubicCurve2D.solveCubic(r)) > 0)
+ {
+ Intersection[] temp = new Intersection[nRoots];
+ int intersections = 0;
+ for (int i = 0; i < nRoots; i++)
+ {
+ double t = r[i];
+ if (t >= 0.0 && t <= 1.0)
+ {
+ // if the line is on an axis, snap the point to that axis.
+ Point2D p = c.evaluatePoint(t);
+ if (dx == 0)
+ p.setLocation(lx0, p.getY());
+ if (dy == 0)
+ p.setLocation(p.getX(), ly0);
+
+ if (p.getX() <= Math.max(lx0, lx1)
+ && p.getX() >= Math.min(lx0, lx1)
+ && p.getY() <= Math.max(ly0, ly1)
+ && p.getY() >= Math.min(ly0, ly1))
+ {
+ double lineparameter = p.distance(l.P1) / l.P2.distance(l.P1);
+ temp[i] = new Intersection(p, lineparameter, t);
+ intersections++;
+ }
+ }
+ else
+ temp[i] = null;
+ }
+
+ if (intersections == 0)
+ return null;
+
+ Intersection[] rValues = new Intersection[intersections];
+ for (int i = 0; i < nRoots; i++)
+ if (temp[i] != null)
+ rValues[--intersections] = temp[i];
+ return (rValues);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the intersection between two lines, or null if there is no
+ * intersection.
+ */
+ private Intersection linesIntersect(LineSegment a, LineSegment b)
+ {
+ Point2D P1 = a.P1;
+ Point2D P2 = a.P2;
+ Point2D P3 = b.P1;
+ Point2D P4 = b.P2;
+
+ if (! Line2D.linesIntersect(P1.getX(), P1.getY(), P2.getX(), P2.getY(),
+ P3.getX(), P3.getY(), P4.getX(), P4.getY()))
+ return null;
+
+ double x1 = P1.getX();
+ double y1 = P1.getY();
+ double rx = P2.getX() - x1;
+ double ry = P2.getY() - y1;
+
+ double x2 = P3.getX();
+ double y2 = P3.getY();
+ double sx = P4.getX() - x2;
+ double sy = P4.getY() - y2;
+
+ double determinant = sx * ry - sy * rx;
+ double nom = (sx * (y2 - y1) + sy * (x1 - x2));
+
+ // Parallel lines don't intersect. At least we pretend they don't.
+ if (Math.abs(determinant) < EPSILON)
+ return null;
+
+ nom = nom / determinant;
+
+ if (nom == 0.0)
+ return null;
+ if (nom == 1.0)
+ return null;
+
+ Point2D p = new Point2D.Double(x1 + nom * rx, y1 + nom * ry);
+
+ return new Intersection(p, p.distance(P1) / P1.distance(P2),
+ p.distance(P3) / P3.distance(P4));
+ }
+
+ /**
+ * Determines if two points are equal, within an error margin
+ * 'snap distance'
+ */
+ private boolean pointEquals(Point2D a, Point2D b)
+ {
+ return (a.equals(b) || a.distance(b) < PE_EPSILON);
+ }
+
+ /**
+ * Helper method
+ * Turns a shape into a Vector of Segments
+ */
+ private Vector makeSegment(Shape s)
+ {
+ Vector paths = new Vector();
+ PathIterator pi = s.getPathIterator(null);
+ double[] coords = new double[6];
+ Segment subpath = null;
+ Segment current = null;
+ double cx;
+ double cy;
+ double subpathx;
+ double subpathy;
+ cx = cy = subpathx = subpathy = 0.0;
+
+ this.windingRule = pi.getWindingRule();
+
+ while (! pi.isDone())
+ {
+ Segment v;
+ switch (pi.currentSegment(coords))
+ {
+ case PathIterator.SEG_MOVETO:
+ if (subpath != null)
+ { // close existing open path
+ current.next = new LineSegment(cx, cy, subpathx, subpathy);
+ current = current.next;
+ current.next = subpath;
+ }
+ subpath = null;
+ subpathx = cx = coords[0];
+ subpathy = cy = coords[1];
+ break;
+
+ // replace 'close' with a line-to.
+ case PathIterator.SEG_CLOSE:
+ if (subpath != null && (subpathx != cx || subpathy != cy))
+ {
+ current.next = new LineSegment(cx, cy, subpathx, subpathy);
+ current = current.next;
+ current.next = subpath;
+ cx = subpathx;
+ cy = subpathy;
+ subpath = null;
+ }
+ else if (subpath != null)
+ {
+ current.next = subpath;
+ subpath = null;
+ }
+ break;
+ case PathIterator.SEG_LINETO:
+ if (cx != coords[0] || cy != coords[1])
+ {
+ v = new LineSegment(cx, cy, coords[0], coords[1]);
+ if (subpath == null)
+ {
+ subpath = current = v;
+ paths.add(subpath);
+ }
+ else
+ {
+ current.next = v;
+ current = current.next;
+ }
+ cx = coords[0];
+ cy = coords[1];
+ }
+ break;
+ case PathIterator.SEG_QUADTO:
+ v = new QuadSegment(cx, cy, coords[0], coords[1], coords[2],
+ coords[3]);
+ if (subpath == null)
+ {
+ subpath = current = v;
+ paths.add(subpath);
+ }
+ else
+ {
+ current.next = v;
+ current = current.next;
+ }
+ cx = coords[2];
+ cy = coords[3];
+ break;
+ case PathIterator.SEG_CUBICTO:
+ v = new CubicSegment(cx, cy, coords[0], coords[1], coords[2],
+ coords[3], coords[4], coords[5]);
+ if (subpath == null)
+ {
+ subpath = current = v;
+ paths.add(subpath);
+ }
+ else
+ {
+ current.next = v;
+ current = current.next;
+ }
+
+ // check if the cubic is self-intersecting
+ double[] lpts = ((CubicSegment) v).getLoop();
+ if (lpts != null)
+ {
+ // if it is, break off the loop into its own path.
+ v.subdivideInsert(lpts[0]);
+ v.next.subdivideInsert((lpts[1] - lpts[0]) / (1.0 - lpts[0]));
+
+ CubicSegment loop = (CubicSegment) v.next;
+ v.next = loop.next;
+ loop.next = loop;
+
+ v.P2 = v.next.P1 = loop.P2 = loop.P1; // snap points
+ paths.add(loop);
+ current = v.next;
+ }
+
+ cx = coords[4];
+ cy = coords[5];
+ break;
+ }
+ pi.next();
+ }
+
+ if (subpath != null)
+ { // close any open path
+ if (subpathx != cx || subpathy != cy)
+ {
+ current.next = new LineSegment(cx, cy, subpathx, subpathy);
+ current = current.next;
+ current.next = subpath;
+ }
+ else
+ current.next = subpath;
+ }
+
+ if (paths.size() == 0)
+ return (null);
+
+ return (paths);
+ }
+
+ /**
+ * Find the intersections of two separate closed paths,
+ * A and B, split the segments at the intersection points,
+ * and create nodes pointing from one to the other
+ */
+ private int createNodes(Segment A, Segment B)
+ {
+ int nNodes = 0;
+
+ Segment a = A;
+ Segment b = B;
+
+ do
+ {
+ do
+ {
+ nNodes += a.splitIntersections(b);
+ b = b.next;
+ }
+ while (b != B);
+
+ a = a.next; // move to the next segment
+ }
+ while (a != A); // until one wrap.
+
+ return (nNodes);
+ }
+
+ /**
+ * Find the intersections of a path with itself.
+ * Splits the segments at the intersection points,
+ * and create nodes pointing from one to the other.
+ */
+ private int createNodesSelf(Segment A)
+ {
+ int nNodes = 0;
+ Segment a = A;
+
+ if (A.next == A)
+ return 0;
+
+ do
+ {
+ Segment b = a.next;
+ do
+ {
+ if (b != a) // necessary
+ nNodes += a.splitIntersections(b);
+ b = b.next;
+ }
+ while (b != A);
+ a = a.next; // move to the next segment
+ }
+ while (a != A); // until one wrap.
+
+ return (nNodes);
+ }
+
+ /**
+ * Deletes paths which are redundant from a list, (i.e. solid areas within
+ * solid areas) Clears any nodes. Sorts the remaining paths into solids
+ * and holes, sets their orientation and sets the solids and holes lists.
+ */
+ private void deleteRedundantPaths(Vector paths)
+ {
+ int npaths = paths.size();
+
+ int[][] contains = new int[npaths][npaths];
+ int[][] windingNumbers = new int[npaths][2];
+ int neg;
+ Rectangle2D[] bb = new Rectangle2D[npaths]; // path bounding boxes
+
+ neg = ((windingRule == PathIterator.WIND_NON_ZERO) ? -1 : 1);
+
+ for (int i = 0; i < npaths; i++)
+ bb[i] = ((Segment) paths.elementAt(i)).getPathBounds();
+
+ // Find which path contains which, assign winding numbers
+ for (int i = 0; i < npaths; i++)
+ {
+ Segment pathA = (Segment) paths.elementAt(i);
+ pathA.nullNodes(); // remove any now-redundant nodes, in case.
+ int windingA = pathA.hasClockwiseOrientation() ? 1 : neg;
+
+ for (int j = 0; j < npaths; j++)
+ if (i != j)
+ {
+ Segment pathB = (Segment) paths.elementAt(j);
+
+ // A contains B
+ if (bb[i].intersects(bb[j]))
+ {
+ Segment s = pathB.next;
+ while (s.P1.getY() == s.P2.getY() && s != pathB)
+ s = s.next;
+ Point2D p = s.getMidPoint();
+ if (pathA.contains(p.getX(), p.getY()))
+ contains[i][j] = windingA;
+ }
+ else
+ // A does not contain B
+ contains[i][j] = 0;
+ }
+ else
+ contains[i][j] = windingA; // i == j
+ }
+
+ for (int i = 0; i < npaths; i++)
+ {
+ windingNumbers[i][0] = 0;
+ for (int j = 0; j < npaths; j++)
+ windingNumbers[i][0] += contains[j][i];
+ windingNumbers[i][1] = contains[i][i];
+ }
+
+ Vector solids = new Vector();
+ Vector holes = new Vector();
+
+ if (windingRule == PathIterator.WIND_NON_ZERO)
+ {
+ for (int i = 0; i < npaths; i++)
+ {
+ if (windingNumbers[i][0] == 0)
+ holes.add(paths.elementAt(i));
+ else if (windingNumbers[i][0] - windingNumbers[i][1] == 0
+ && Math.abs(windingNumbers[i][0]) == 1)
+ solids.add(paths.elementAt(i));
+ }
+ }
+ else
+ {
+ windingRule = PathIterator.WIND_NON_ZERO;
+ for (int i = 0; i < npaths; i++)
+ {
+ if ((windingNumbers[i][0] & 1) == 0)
+ holes.add(paths.elementAt(i));
+ else if ((windingNumbers[i][0] & 1) == 1)
+ solids.add(paths.elementAt(i));
+ }
+ }
+
+ setDirection(holes, false);
+ setDirection(solids, true);
+ this.holes = holes;
+ this.solids = solids;
+ }
+
+ /**
+ * Sets the winding direction of a Vector of paths
+ * @param clockwise gives the direction,
+ * true = clockwise, false = counter-clockwise
+ */
+ private void setDirection(Vector paths, boolean clockwise)
+ {
+ Segment v;
+ for (int i = 0; i < paths.size(); i++)
+ {
+ v = (Segment) paths.elementAt(i);
+ if (clockwise != v.hasClockwiseOrientation())
+ v.reverseAll();
+ }
+ }
+
+ /**
+ * Class representing a linked-list of vertices forming a closed polygon,
+ * convex or concave, without holes.
+ */
+ private abstract class Segment implements Cloneable
+ {
+ // segment type, PathIterator segment types are used.
+ Point2D P1;
+ Point2D P2;
+ Segment next;
+ Segment node;
+
+ Segment()
+ {
+ P1 = P2 = null;
+ node = next = null;
+ }
+
+ /**
+ * Reverses the direction of a single segment
+ */
+ abstract void reverseCoords();
+
+ /**
+ * Returns the segment's midpoint
+ */
+ abstract Point2D getMidPoint();
+
+ /**
+ * Returns the bounding box of this segment
+ */
+ abstract Rectangle2D getBounds();
+
+ /**
+ * Transforms a single segment
+ */
+ abstract void transform(AffineTransform at);
+
+ /**
+ * Returns the PathIterator type of a segment
+ */
+ abstract int getType();
+
+ /**
+ */
+ abstract int splitIntersections(Segment b);
+
+ /**
+ * Returns the PathIterator coords of a segment
+ */
+ abstract int pathIteratorFormat(double[] coords);
+
+ /**
+ * Returns the number of intersections on the positive X axis,
+ * with the origin at (x,y), used for contains()-testing
+ *
+ * (Although that could be done by the line-intersect methods,
+ * a dedicated method is better to guarantee consitent handling
+ * of endpoint-special-cases)
+ */
+ abstract int rayCrossing(double x, double y);
+
+ /**
+ * Subdivides the segment at parametric value t, inserting
+ * the new segment into the linked list after this,
+ * such that this becomes [0,t] and this.next becomes [t,1]
+ */
+ abstract void subdivideInsert(double t);
+
+ /**
+ * Returns twice the area of a curve, relative the P1-P2 line
+ * Used for area calculations.
+ */
+ abstract double curveArea();
+
+ /**
+ * Compare two segments.
+ */
+ abstract boolean equals(Segment b);
+
+ /**
+ * Determines if this path of segments contains the point (x,y)
+ */
+ boolean contains(double x, double y)
+ {
+ Segment v = this;
+ int crossings = 0;
+ do
+ {
+ int n = v.rayCrossing(x, y);
+ crossings += n;
+ v = v.next;
+ }
+ while (v != this);
+ return ((crossings & 1) == 1);
+ }
+
+ /**
+ * Nulls all nodes of the path. Clean up any 'hairs'.
+ */
+ void nullNodes()
+ {
+ Segment v = this;
+ do
+ {
+ v.node = null;
+ v = v.next;
+ }
+ while (v != this);
+ }
+
+ /**
+ * Transforms each segment in the closed path
+ */
+ void transformSegmentList(AffineTransform at)
+ {
+ Segment v = this;
+ do
+ {
+ v.transform(at);
+ v = v.next;
+ }
+ while (v != this);
+ }
+
+ /**
+ * Determines the winding direction of the path
+ * By the sign of the area.
+ */
+ boolean hasClockwiseOrientation()
+ {
+ return (getSignedArea() > 0.0);
+ }
+
+ /**
+ * Returns the bounds of this path
+ */
+ public Rectangle2D getPathBounds()
+ {
+ double xmin;
+ double xmax;
+ double ymin;
+ double ymax;
+ xmin = xmax = P1.getX();
+ ymin = ymax = P1.getY();
+
+ Segment v = this;
+ do
+ {
+ Rectangle2D r = v.getBounds();
+ xmin = Math.min(r.getMinX(), xmin);
+ ymin = Math.min(r.getMinY(), ymin);
+ xmax = Math.max(r.getMaxX(), xmax);
+ ymax = Math.max(r.getMaxY(), ymax);
+ v = v.next;
+ }
+ while (v != this);
+
+ return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
+ }
+
+ /**
+ * Calculates twice the signed area of the path;
+ */
+ double getSignedArea()
+ {
+ Segment s;
+ double area = 0.0;
+
+ s = this;
+ do
+ {
+ area += s.curveArea();
+
+ area += s.P1.getX() * s.next.P1.getY()
+ - s.P1.getY() * s.next.P1.getX();
+ s = s.next;
+ }
+ while (s != this);
+
+ return area;
+ }
+
+ /**
+ * Reverses the orientation of the whole polygon
+ */
+ void reverseAll()
+ {
+ reverseCoords();
+ Segment v = next;
+ Segment former = this;
+ while (v != this)
+ {
+ v.reverseCoords();
+ Segment vnext = v.next;
+ v.next = former;
+ former = v;
+ v = vnext;
+ }
+ next = former;
+ }
+
+ /**
+ * Inserts a Segment after this one
+ */
+ void insert(Segment v)
+ {
+ Segment n = next;
+ next = v;
+ v.next = n;
+ }
+
+ /**
+ * Returns if this segment path is polygonal
+ */
+ boolean isPolygonal()
+ {
+ Segment v = this;
+ do
+ {
+ if (! (v instanceof LineSegment))
+ return false;
+ v = v.next;
+ }
+ while (v != this);
+ return true;
+ }
+
+ /**
+ * Clones this path
+ */
+ Segment cloneSegmentList() throws CloneNotSupportedException
+ {
+ Vector list = new Vector();
+ Segment v = next;
+
+ while (v != this)
+ {
+ list.add(v);
+ v = v.next;
+ }
+
+ Segment clone = (Segment) this.clone();
+ v = clone;
+ for (int i = 0; i < list.size(); i++)
+ {
+ clone.next = (Segment) ((Segment) list.elementAt(i)).clone();
+ clone = clone.next;
+ }
+ clone.next = v;
+ return v;
+ }
+
+ /**
+ * Creates a node between this segment and segment b
+ * at the given intersection
+ * @return the number of nodes created (0 or 1)
+ */
+ int createNode(Segment b, Intersection i)
+ {
+ Point2D p = i.p;
+ if ((pointEquals(P1, p) || pointEquals(P2, p))
+ && (pointEquals(b.P1, p) || pointEquals(b.P2, p)))
+ return 0;
+
+ subdivideInsert(i.ta);
+ b.subdivideInsert(i.tb);
+
+ // snap points
+ b.P2 = b.next.P1 = P2 = next.P1 = i.p;
+
+ node = b.next;
+ b.node = next;
+ return 1;
+ }
+
+ /**
+ * Creates multiple nodes from a list of intersections,
+ * This must be done in the order of ascending parameters,
+ * and the parameters must be recalculated in accordance
+ * with each split.
+ * @return the number of nodes created
+ */
+ protected int createNodes(Segment b, Intersection[] x)
+ {
+ Vector v = new Vector();
+ for (int i = 0; i < x.length; i++)
+ {
+ Point2D p = x[i].p;
+ if (! ((pointEquals(P1, p) || pointEquals(P2, p))
+ && (pointEquals(b.P1, p) || pointEquals(b.P2, p))))
+ v.add(x[i]);
+ }
+
+ int nNodes = v.size();
+ Intersection[] A = new Intersection[nNodes];
+ Intersection[] B = new Intersection[nNodes];
+ for (int i = 0; i < nNodes; i++)
+ A[i] = B[i] = (Intersection) v.elementAt(i);
+
+ // Create two lists sorted by the parameter
+ // Bubble sort, OK I suppose, since the number of intersections
+ // cannot be larger than 9 (cubic-cubic worst case) anyway
+ for (int i = 0; i < nNodes - 1; i++)
+ {
+ for (int j = i + 1; j < nNodes; j++)
+ {
+ if (A[i].ta > A[j].ta)
+ {
+ Intersection swap = A[i];
+ A[i] = A[j];
+ A[j] = swap;
+ }
+ if (B[i].tb > B[j].tb)
+ {
+ Intersection swap = B[i];
+ B[i] = B[j];
+ B[j] = swap;
+ }
+ }
+ }
+ // subdivide a
+ Segment s = this;
+ for (int i = 0; i < nNodes; i++)
+ {
+ s.subdivideInsert(A[i].ta);
+
+ // renormalize the parameters
+ for (int j = i + 1; j < nNodes; j++)
+ A[j].ta = (A[j].ta - A[i].ta) / (1.0 - A[i].ta);
+
+ A[i].seg = s;
+ s = s.next;
+ }
+
+ // subdivide b, set nodes
+ s = b;
+ for (int i = 0; i < nNodes; i++)
+ {
+ s.subdivideInsert(B[i].tb);
+
+ for (int j = i + 1; j < nNodes; j++)
+ B[j].tb = (B[j].tb - B[i].tb) / (1.0 - B[i].tb);
+
+ // set nodes
+ B[i].seg.node = s.next; // node a -> b
+ s.node = B[i].seg.next; // node b -> a
+
+ // snap points
+ B[i].seg.P2 = B[i].seg.next.P1 = s.P2 = s.next.P1 = B[i].p;
+ s = s.next;
+ }
+ return nNodes;
+ }
+
+ /**
+ * Determines if two paths are equal.
+ * Colinear line segments are ignored in the comparison.
+ */
+ boolean pathEquals(Segment B)
+ {
+ if (! getPathBounds().equals(B.getPathBounds()))
+ return false;
+
+ Segment startA = getTopLeft();
+ Segment startB = B.getTopLeft();
+ Segment a = startA;
+ Segment b = startB;
+ do
+ {
+ if (! a.equals(b))
+ return false;
+
+ if (a instanceof LineSegment)
+ a = ((LineSegment) a).lastCoLinear();
+ if (b instanceof LineSegment)
+ b = ((LineSegment) b).lastCoLinear();
+
+ a = a.next;
+ b = b.next;
+ }
+ while (a != startA && b != startB);
+ return true;
+ }
+
+ /**
+ * Return the segment with the top-leftmost first point
+ */
+ Segment getTopLeft()
+ {
+ Segment v = this;
+ Segment tl = this;
+ do
+ {
+ if (v.P1.getY() < tl.P1.getY())
+ tl = v;
+ else if (v.P1.getY() == tl.P1.getY())
+ {
+ if (v.P1.getX() < tl.P1.getX())
+ tl = v;
+ }
+ v = v.next;
+ }
+ while (v != this);
+ return tl;
+ }
+
+ /**
+ * Returns if the path has a segment outside a shape
+ */
+ boolean isSegmentOutside(Shape shape)
+ {
+ return ! shape.contains(getMidPoint());
+ }
+ } // class Segment
+
+ private 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);
+ }
+
+ /**
+ * Transforms the segment
+ */
+ void transform(AffineTransform at)
+ {
+ P1 = at.transform(P1, null);
+ P2 = at.transform(P2, null);
+ }
+
+ /**
+ * Swap start and end points
+ */
+ void reverseCoords()
+ {
+ Point2D p = P1;
+ P1 = P2;
+ P2 = p;
+ }
+
+ /**
+ * Returns the segment's midpoint
+ */
+ Point2D getMidPoint()
+ {
+ return (new Point2D.Double(0.5 * (P1.getX() + P2.getX()),
+ 0.5 * (P1.getY() + P2.getY())));
+ }
+
+ /**
+ * Returns twice the area of a curve, relative the P1-P2 line
+ * Obviously, a line does not enclose any area besides the line
+ */
+ double curveArea()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the PathIterator type of a segment
+ */
+ int getType()
+ {
+ return (PathIterator.SEG_LINETO);
+ }
+
+ /**
+ * Subdivides the segment at parametric value t, inserting
+ * the new segment into the linked list after this,
+ * such that this becomes [0,t] and this.next becomes [t,1]
+ */
+ void subdivideInsert(double t)
+ {
+ Point2D p = new Point2D.Double((P2.getX() - P1.getX()) * t + P1.getX(),
+ (P2.getY() - P1.getY()) * t + P1.getY());
+ insert(new LineSegment(p, P2));
+ P2 = p;
+ next.node = node;
+ node = null;
+ }
+
+ /**
+ * Determines if two line segments are strictly colinear
+ */
+ boolean isCoLinear(LineSegment b)
+ {
+ double x1 = P1.getX();
+ double y1 = P1.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+ double x3 = b.P1.getX();
+ double y3 = b.P1.getY();
+ double x4 = b.P2.getX();
+ double y4 = b.P2.getY();
+
+ if ((y1 - y3) * (x4 - x3) - (x1 - x3) * (y4 - y3) != 0.0)
+ return false;
+
+ return ((x2 - x1) * (y4 - y3) - (y2 - y1) * (x4 - x3) == 0.0);
+ }
+
+ /**
+ * Return the last segment colinear with this one.
+ * Used in comparing paths.
+ */
+ Segment lastCoLinear()
+ {
+ Segment prev = this;
+ Segment v = next;
+
+ while (v instanceof LineSegment)
+ {
+ if (isCoLinear((LineSegment) v))
+ {
+ prev = v;
+ v = v.next;
+ }
+ else
+ return prev;
+ }
+ return prev;
+ }
+
+ /**
+ * Compare two segments.
+ * We must take into account that the lines may be broken into colinear
+ * subsegments and ignore them.
+ */
+ boolean equals(Segment b)
+ {
+ if (! (b instanceof LineSegment))
+ return false;
+ Point2D p1 = P1;
+ Point2D p3 = b.P1;
+
+ if (! p1.equals(p3))
+ return false;
+
+ Point2D p2 = lastCoLinear().P2;
+ Point2D p4 = ((LineSegment) b).lastCoLinear().P2;
+ return (p2.equals(p4));
+ }
+
+ /**
+ * Returns a line segment
+ */
+ int pathIteratorFormat(double[] coords)
+ {
+ coords[0] = P2.getX();
+ coords[1] = P2.getY();
+ return (PathIterator.SEG_LINETO);
+ }
+
+ /**
+ * Returns if the line has intersections.
+ */
+ boolean hasIntersections(Segment b)
+ {
+ if (b instanceof LineSegment)
+ return (linesIntersect(this, (LineSegment) b) != null);
+
+ if (b instanceof QuadSegment)
+ return (lineQuadIntersect(this, (QuadSegment) b) != null);
+
+ if (b instanceof CubicSegment)
+ return (lineCubicIntersect(this, (CubicSegment) b) != null);
+
+ return false;
+ }
+
+ /**
+ * Splits intersections into nodes,
+ * This one handles line-line, line-quadratic, line-cubic
+ */
+ int splitIntersections(Segment b)
+ {
+ if (b instanceof LineSegment)
+ {
+ Intersection i = linesIntersect(this, (LineSegment) b);
+
+ if (i == null)
+ return 0;
+
+ return createNode(b, i);
+ }
+
+ Intersection[] x = null;
+
+ if (b instanceof QuadSegment)
+ x = lineQuadIntersect(this, (QuadSegment) b);
+
+ if (b instanceof CubicSegment)
+ x = lineCubicIntersect(this, (CubicSegment) b);
+
+ if (x == null)
+ return 0;
+
+ if (x.length == 1)
+ return createNode(b, (Intersection) x[0]);
+
+ return createNodes(b, x);
+ }
+
+ /**
+ * Returns the bounding box of this segment
+ */
+ Rectangle2D getBounds()
+ {
+ return (new Rectangle2D.Double(Math.min(P1.getX(), P2.getX()),
+ Math.min(P1.getY(), P2.getY()),
+ Math.abs(P1.getX() - P2.getX()),
+ Math.abs(P1.getY() - P2.getY())));
+ }
+
+ /**
+ * Returns the number of intersections on the positive X axis,
+ * with the origin at (x,y), used for contains()-testing
+ */
+ int rayCrossing(double x, double y)
+ {
+ double x0 = P1.getX() - x;
+ double y0 = P1.getY() - y;
+ double x1 = P2.getX() - x;
+ double y1 = P2.getY() - y;
+
+ if (y0 * y1 > 0)
+ return 0;
+
+ if (x0 < 0 && x1 < 0)
+ return 0;
+
+ if (y0 == 0.0)
+ y0 -= EPSILON;
+
+ if (y1 == 0.0)
+ y1 -= EPSILON;
+
+ if (Line2D.linesIntersect(x0, y0, x1, y1,
+ EPSILON, 0.0, Double.MAX_VALUE, 0.0))
+ return 1;
+ return 0;
+ }
+ } // class LineSegment
+
+ /**
+ * 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.
+ */
+ private class QuadSegment extends Segment
+ {
+ Point2D cp; // control point
+
+ /**
+ * Constructor, takes the coordinates of the start, control,
+ * and end point, respectively.
+ */
+ 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);
+ }
+
+ /**
+ * Clones this segment
+ */
+ public Object clone()
+ {
+ return new QuadSegment(P1.getX(), P1.getY(), cp.getX(), cp.getY(),
+ P2.getX(), P2.getY());
+ }
+
+ /**
+ * Returns twice the area of a curve, relative the P1-P2 line
+ *
+ * The area formula can be derived by using Green's formula in the
+ * plane on the parametric form of the bezier.
+ */
+ double curveArea()
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp.getX();
+ double y1 = cp.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+
+ double P = (y2 - 2 * y1 + y0);
+ double Q = 2 * (y1 - y0);
+ double R = y0;
+
+ double A = (x2 - 2 * x1 + x0);
+ double B = 2 * (x1 - x0);
+ double C = x0;
+
+ double area = (B * P - A * Q) / 3.0;
+ return (area);
+ }
+
+ /**
+ * Compare two segments.
+ */
+ boolean equals(Segment b)
+ {
+ if (! (b instanceof QuadSegment))
+ return false;
+
+ return (P1.equals(b.P1) && cp.equals(((QuadSegment) b).cp)
+ && P2.equals(b.P2));
+ }
+
+ /**
+ * Returns a Point2D corresponding to the parametric value t
+ * of the curve
+ */
+ Point2D evaluatePoint(double t)
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp.getX();
+ double y1 = cp.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+
+ return new Point2D.Double(t * t * (x2 - 2 * x1 + x0) + 2 * t * (x1 - x0)
+ + x0,
+ t * t * (y2 - 2 * y1 + y0) + 2 * t * (y1 - y0)
+ + y0);
+ }
+
+ /**
+ * Returns the bounding box of this segment
+ */
+ Rectangle2D getBounds()
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp.getX();
+ double y1 = cp.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+ double r0;
+ double r1;
+
+ double xmax = Math.max(x0, x2);
+ double ymax = Math.max(y0, y2);
+ double xmin = Math.min(x0, x2);
+ double ymin = Math.min(y0, y2);
+
+ r0 = 2 * (y1 - y0);
+ r1 = 2 * (y2 - 2 * y1 + y0);
+ if (r1 != 0.0)
+ {
+ double t = -r0 / r1;
+ if (t > 0.0 && t < 1.0)
+ {
+ double y = evaluatePoint(t).getY();
+ ymax = Math.max(y, ymax);
+ ymin = Math.min(y, ymin);
+ }
+ }
+ r0 = 2 * (x1 - x0);
+ r1 = 2 * (x2 - 2 * x1 + x0);
+ if (r1 != 0.0)
+ {
+ double t = -r0 / r1;
+ if (t > 0.0 && t < 1.0)
+ {
+ double x = evaluatePoint(t).getY();
+ xmax = Math.max(x, xmax);
+ xmin = Math.min(x, xmin);
+ }
+ }
+
+ return (new Rectangle2D.Double(xmin, ymin, xmax - xmin, ymax - ymin));
+ }
+
+ /**
+ * Returns a cubic segment corresponding to this curve
+ */
+ CubicSegment getCubicSegment()
+ {
+ double x1 = P1.getX() + 2.0 * (cp.getX() - P1.getX()) / 3.0;
+ double y1 = P1.getY() + 2.0 * (cp.getY() - P1.getY()) / 3.0;
+ double x2 = cp.getX() + (P2.getX() - cp.getX()) / 3.0;
+ double y2 = cp.getY() + (P2.getY() - cp.getY()) / 3.0;
+
+ return new CubicSegment(P1.getX(), P1.getY(), x1, y1, x2, y2, P2.getX(),
+ P2.getY());
+ }
+
+ /**
+ * Returns the segment's midpoint
+ */
+ Point2D getMidPoint()
+ {
+ return evaluatePoint(0.5);
+ }
+
+ /**
+ * Returns the PathIterator type of a segment
+ */
+ int getType()
+ {
+ return (PathIterator.SEG_QUADTO);
+ }
+
+ /**
+ * Returns the PathIterator coords of a segment
+ */
+ int pathIteratorFormat(double[] coords)
+ {
+ coords[0] = cp.getX();
+ coords[1] = cp.getY();
+ coords[2] = P2.getX();
+ coords[3] = P2.getY();
+ return (PathIterator.SEG_QUADTO);
+ }
+
+ /**
+ * Returns the number of intersections on the positive X axis,
+ * with the origin at (x,y), used for contains()-testing
+ */
+ int rayCrossing(double x, double y)
+ {
+ double x0 = P1.getX() - x;
+ double y0 = P1.getY() - y;
+ double x1 = cp.getX() - x;
+ double y1 = cp.getY() - y;
+ double x2 = P2.getX() - x;
+ double y2 = P2.getY() - y;
+ double[] r = new double[3];
+ int nRoots;
+ int nCrossings = 0;
+
+ /* check if curve may intersect X+ axis. */
+ if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0) && (y0 * y1 <= 0 || y1 * y2 <= 0))
+ {
+ if (y0 == 0.0)
+ y0 -= EPSILON;
+ if (y2 == 0.0)
+ y2 -= EPSILON;
+
+ r[0] = y0;
+ r[1] = 2 * (y1 - y0);
+ r[2] = (y2 - 2 * y1 + y0);
+
+ nRoots = QuadCurve2D.solveQuadratic(r);
+ for (int i = 0; i < nRoots; i++)
+ if (r[i] > 0.0f && r[i] < 1.0f)
+ {
+ double t = r[i];
+ if (t * t * (x2 - 2 * x1 + x0) + 2 * t * (x1 - x0) + x0 > 0.0)
+ nCrossings++;
+ }
+ }
+ return nCrossings;
+ }
+
+ /**
+ * Swap start and end points
+ */
+ void reverseCoords()
+ {
+ Point2D temp = P1;
+ P1 = P2;
+ P2 = temp;
+ }
+
+ /**
+ * Splits intersections into nodes,
+ * This one handles quadratic-quadratic only,
+ * Quadratic-line is passed on to the LineSegment class,
+ * Quadratic-cubic is passed on to the CubicSegment class
+ */
+ int splitIntersections(Segment b)
+ {
+ if (b instanceof LineSegment)
+ return (b.splitIntersections(this));
+
+ if (b instanceof CubicSegment)
+ return (b.splitIntersections(this));
+
+ if (b instanceof QuadSegment)
+ {
+ // Use the cubic-cubic intersection routine for quads as well,
+ // Since a quadratic can be exactly described as a cubic, this
+ // should not be a problem;
+ // The recursion depth will be the same in any case.
+ Intersection[] x = cubicCubicIntersect(getCubicSegment(),
+ ((QuadSegment) b)
+ .getCubicSegment());
+ if (x == null)
+ return 0;
+
+ if (x.length == 1)
+ return createNode(b, (Intersection) x[0]);
+
+ return createNodes(b, x);
+ }
+ return 0;
+ }
+
+ /**
+ * Subdivides the segment at parametric value t, inserting
+ * the new segment into the linked list after this,
+ * such that this becomes [0,t] and this.next becomes [t,1]
+ */
+ void subdivideInsert(double t)
+ {
+ double x0 = P1.getX();
+ double y0 = P1.getY();
+ double x1 = cp.getX();
+ double y1 = cp.getY();
+ double x2 = P2.getX();
+ double y2 = P2.getY();
+
+ double p10x = x0 + t * (x1 - x0);
+ double p10y = y0 + t * (y1 - y0);
+ double p11x = x1 + t * (x2 - x1);
+ double p11y = y1 + t * (y2 - y1);
+ double p20x = p10x + t * (p11x - p10x);
+ double p20y = p10y + t * (p11y - p10y);
+
+ insert(new QuadSegment(p20x, p20y, p11x, p11y, x2, y2));
+ P2 = next.P1;
+ cp.setLocation(p10x, p10y);
+
+ next.node = node;
+ node = null;
+ }
+
+ /**
+ * Transforms the segment
+ */
+ void transform(AffineTransform at)
+ {
+ P1 = at.transform(P1, null);
+ P2 = at.transform(P2, null);
+ cp = at.transform(cp, null);
+ }
+ } // class QuadSegment
+
+ /**
+ * Cubic Bezier curve segment
+ */
+ private class CubicSegment extends Segment
+ {
+ Point2D cp1; // control points
+ 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);
+ }
+
+ /**
+ * 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());
+ }
+
+ /**
+ * Returns twice the area of a curve, relative the P1-P2 line
+ *
+ * The area formula can be derived by using Green's formula in the
+ * plane on the parametric form of the bezier.
+ */
+ double curveArea()
+ {
+ 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 P = y3 - 3 * y2 + 3 * y1 - y0;
+ double Q = 3 * (y2 + y0 - 2 * y1);
+ double R = 3 * (y1 - y0);
+ double S = y0;
+
+ double A = x3 - 3 * x2 + 3 * x1 - x0;
+ double B = 3 * (x2 + x0 - 2 * x1);
+ double C = 3 * (x1 - x0);
+ double D = x0;
+
+ double area = (B * P - A * Q) / 5.0 + (C * P - A * R) / 2.0
+ + (C * Q - B * R) / 3.0;
+
+ return (area);
+ }
+
+ /**
+ * Compare two segments.
+ */
+ boolean equals(Segment b)
+ {
+ if (! (b instanceof CubicSegment))
+ return false;
+
+ return (P1.equals(b.P1) && cp1.equals(((CubicSegment) b).cp1)
+ && cp2.equals(((CubicSegment) b).cp2) && P2.equals(b.P2));
+ }
+
+ /**
+ * Returns a Point2D corresponding to the parametric value t
+ * of the curve
+ */
+ Point2D evaluatePoint(double t)
+ {
+ 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();
+
+ return new Point2D.Double(-(t * t * t) * (x0 - 3 * x1 + 3 * x2 - x3)
+ + 3 * t * t * (x0 - 2 * x1 + x2)
+ + 3 * t * (x1 - x0) + x0,
+ -(t * t * t) * (y0 - 3 * y1 + 3 * y2 - y3)
+ + 3 * t * t * (y0 - 2 * y1 + y2)
+ + 3 * t * (y1 - y0) + y0);
+ }
+
+ /**
+ * Returns the bounding box of this segment
+ */
+ Rectangle2D getBounds()
+ {
+ 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[] r = new double[3];
+
+ double xmax = Math.max(x0, x3);
+ double ymax = Math.max(y0, y3);
+ double xmin = Math.min(x0, x3);
+ double ymin = Math.min(y0, y3);
+
+ r[0] = 3 * (y1 - y0);
+ r[1] = 6.0 * (y2 + y0 - 2 * y1);
+ r[2] = 3.0 * (y3 - 3 * y2 + 3 * y1 - y0);
+
+ int n = QuadCurve2D.solveQuadratic(r);
+ for (int i = 0; i < n; i++)
+ {
+ double t = r[i];
+ if (t > 0 && t < 1.0)
+ {
+ double y = evaluatePoint(t).getY();
+ ymax = Math.max(y, ymax);
+ ymin = Math.min(y, ymin);
+ }
+ }
+
+ r[0] = 3 * (x1 - x0);
+ r[1] = 6.0 * (x2 + x0 - 2 * x1);
+ r[2] = 3.0 * (x3 - 3 * x2 + 3 * x1 - x0);
+ n = QuadCurve2D.solveQuadratic(r);
+ for (int i = 0; i < n; i++)
+ {
+ double t = r[i];
+ if (t > 0 && t < 1.0)
+ {
+ double x = evaluatePoint(t).getX();
+ xmax = Math.max(x, xmax);
+ xmin = Math.min(x, xmin);
+ }
+ }
+ return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
+ }
+
+ /**
+ * Returns a CubicCurve2D object corresponding to this segment.
+ */
+ CubicCurve2D getCubicCurve2D()
+ {
+ return new CubicCurve2D.Double(P1.getX(), P1.getY(), cp1.getX(),
+ cp1.getY(), cp2.getX(), cp2.getY(),
+ P2.getX(), P2.getY());
+ }
+
+ /**
+ * Returns the parametric points of self-intersection if the cubic
+ * is self-intersecting, null otherwise.
+ */
+ double[] getLoop()
+ {
+ 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[] r = new double[4];
+ double k;
+ double R;
+ double T;
+ double A;
+ double B;
+ double[] results = new double[2];
+
+ R = x3 - 3 * x2 + 3 * x1 - x0;
+ T = y3 - 3 * y2 + 3 * y1 - y0;
+
+ // A qudratic
+ if (R == 0.0 && T == 0.0)
+ return null;
+
+ // true cubic
+ if (R != 0.0 && T != 0.0)
+ {
+ A = 3 * (x2 + x0 - 2 * x1) / R;
+ B = 3 * (x1 - x0) / R;
+
+ double P = 3 * (y2 + y0 - 2 * y1) / T;
+ double Q = 3 * (y1 - y0) / T;
+
+ if (A == P || Q == B)
+ return null;
+
+ k = (Q - B) / (A - P);
+ }
+ else
+ {
+ if (R == 0.0)
+ {
+ // quadratic in x
+ k = -(3 * (x1 - x0)) / (3 * (x2 + x0 - 2 * x1));
+ A = 3 * (y2 + y0 - 2 * y1) / T;
+ B = 3 * (y1 - y0) / T;
+ }
+ else
+ {
+ // quadratic in y
+ k = -(3 * (y1 - y0)) / (3 * (y2 + y0 - 2 * y1));
+ A = 3 * (x2 + x0 - 2 * x1) / R;
+ B = 3 * (x1 - x0) / R;
+ }
+ }
+
+ r[0] = -k * k * k - A * k * k - B * k;
+ r[1] = 3 * k * k + 2 * k * A + 2 * B;
+ r[2] = -3 * k;
+ r[3] = 2;
+
+ int n = CubicCurve2D.solveCubic(r);
+ if (n != 3)
+ return null;
+
+ // sort r
+ double t;
+ for (int i = 0; i < 2; i++)
+ for (int j = i + 1; j < 3; j++)
+ if (r[j] < r[i])
+ {
+ t = r[i];
+ r[i] = r[j];
+ r[j] = t;
+ }
+
+ if (Math.abs(r[0] + r[2] - k) < 1E-13)
+ if (r[0] >= 0.0 && r[0] <= 1.0 && r[2] >= 0.0 && r[2] <= 1.0)
+ if (evaluatePoint(r[0]).distance(evaluatePoint(r[2])) < PE_EPSILON * 10)
+ { // we snap the points anyway
+ results[0] = r[0];
+ results[1] = r[2];
+ return (results);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the segment's midpoint
+ */
+ Point2D getMidPoint()
+ {
+ return evaluatePoint(0.5);
+ }
+
+ /**
+ * Returns the PathIterator type of a segment
+ */
+ int getType()
+ {
+ return (PathIterator.SEG_CUBICTO);
+ }
+
+ /**
+ * Returns the PathIterator coords of a segment
+ */
+ int pathIteratorFormat(double[] coords)
+ {
+ coords[0] = cp1.getX();
+ coords[1] = cp1.getY();
+ coords[2] = cp2.getX();
+ coords[3] = cp2.getY();
+ coords[4] = P2.getX();
+ coords[5] = P2.getY();
+ return (PathIterator.SEG_CUBICTO);
+ }
+
+ /**
+ * Returns the number of intersections on the positive X axis,
+ * with the origin at (x,y), used for contains()-testing
+ */
+ int rayCrossing(double x, double y)
+ {
+ double x0 = P1.getX() - x;
+ double y0 = P1.getY() - y;
+ double x1 = cp1.getX() - x;
+ double y1 = cp1.getY() - y;
+ double x2 = cp2.getX() - x;
+ double y2 = cp2.getY() - y;
+ double x3 = P2.getX() - x;
+ double y3 = P2.getY() - y;
+ double[] r = new double[4];
+ int nRoots;
+ int nCrossings = 0;
+
+ /* check if curve may intersect X+ axis. */
+ if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0 || x3 > 0.0)
+ && (y0 * y1 <= 0 || y1 * y2 <= 0 || y2 * y3 <= 0))
+ {
+ if (y0 == 0.0)
+ y0 -= EPSILON;
+ if (y3 == 0.0)
+ y3 -= EPSILON;
+
+ r[0] = y0;
+ r[1] = 3 * (y1 - y0);
+ r[2] = 3 * (y2 + y0 - 2 * y1);
+ r[3] = y3 - 3 * y2 + 3 * y1 - y0;
+
+ if ((nRoots = CubicCurve2D.solveCubic(r)) > 0)
+ for (int i = 0; i < nRoots; i++)
+ {
+ if (r[i] > 0.0 && r[i] < 1.0)
+ {
+ double t = r[i];
+ if (-(t * t * t) * (x0 - 3 * x1 + 3 * x2 - x3)
+ + 3 * t * t * (x0 - 2 * x1 + x2) + 3 * t * (x1 - x0)
+ + x0 > 0.0)
+ nCrossings++;
+ }
+ }
+ }
+ return nCrossings;
+ }
+
+ /**
+ * Swap start and end points
+ */
+ void reverseCoords()
+ {
+ Point2D p = P1;
+ P1 = P2;
+ P2 = p;
+ p = cp1; // swap control points
+ cp1 = cp2;
+ cp2 = p;
+ }
+
+ /**
+ * Splits intersections into nodes,
+ * This one handles cubic-cubic and cubic-quadratic intersections
+ */
+ int splitIntersections(Segment b)
+ {
+ if (b instanceof LineSegment)
+ return (b.splitIntersections(this));
+
+ Intersection[] x = null;
+
+ if (b instanceof QuadSegment)
+ x = cubicCubicIntersect(this, ((QuadSegment) b).getCubicSegment());
+
+ if (b instanceof CubicSegment)
+ x = cubicCubicIntersect(this, (CubicSegment) b);
+
+ if (x == null)
+ return 0;
+
+ if (x.length == 1)
+ return createNode(b, x[0]);
+
+ return createNodes(b, x);
+ }
+
+ /**
+ * Subdivides the segment at parametric value t, inserting
+ * the new segment into the linked list after this,
+ * such that this becomes [0,t] and this.next becomes [t,1]
+ */
+ void subdivideInsert(double t)
+ {
+ CubicSegment s = (CubicSegment) clone();
+ double p1x = (s.cp1.getX() - s.P1.getX()) * t + s.P1.getX();
+ double p1y = (s.cp1.getY() - s.P1.getY()) * t + s.P1.getY();
+
+ double px = (s.cp2.getX() - s.cp1.getX()) * t + s.cp1.getX();
+ double py = (s.cp2.getY() - s.cp1.getY()) * t + s.cp1.getY();
+
+ s.cp2.setLocation((s.P2.getX() - s.cp2.getX()) * t + s.cp2.getX(),
+ (s.P2.getY() - s.cp2.getY()) * t + s.cp2.getY());
+
+ s.cp1.setLocation((s.cp2.getX() - px) * t + px,
+ (s.cp2.getY() - py) * t + py);
+
+ double p2x = (px - p1x) * t + p1x;
+ double p2y = (py - p1y) * t + p1y;
+
+ double p3x = (s.cp1.getX() - p2x) * t + p2x;
+ double p3y = (s.cp1.getY() - p2y) * t + p2y;
+ s.P1.setLocation(p3x, p3y);
+
+ // insert new curve
+ insert(s);
+
+ // set this curve
+ cp1.setLocation(p1x, p1y);
+ cp2.setLocation(p2x, p2y);
+ P2 = s.P1;
+ next.node = node;
+ node = null;
+ }
+
+ /**
+ * Transforms the segment
+ */
+ void transform(AffineTransform at)
+ {
+ P1 = at.transform(P1, null);
+ P2 = at.transform(P2, null);
+ cp1 = at.transform(cp1, null);
+ cp2 = at.transform(cp2, null);
+ }
+ } // class CubicSegment
} // class Area
diff --git a/libjava/java/awt/geom/CubicCurve2D.java b/libjava/java/awt/geom/CubicCurve2D.java
index 56b90e99838..20373061d18 100644
--- a/libjava/java/awt/geom/CubicCurve2D.java
+++ b/libjava/java/awt/geom/CubicCurve2D.java
@@ -59,6 +59,7 @@ import java.util.NoSuchElementException;
public abstract class CubicCurve2D implements Shape, Cloneable
{
private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
+ private static final double EPSILON = 1E-10;
/**
* Constructs a new CubicCurve2D. Typical users will want to
@@ -1089,21 +1090,21 @@ public abstract class CubicCurve2D implements Shape, Cloneable
If this is not done, bad behaviour may result for points on that axis.*/
if (a0 == 0.0 || a3 == 0.0)
{
- double small = getFlatness() * (1E-10);
+ double small = getFlatness() * EPSILON;
if (a0 == 0.0)
- a0 += small;
+ a0 -= small;
if (a3 == 0.0)
- a3 += small;
+ a3 -= small;
}
if (useYaxis)
{
- if (Line2D.linesIntersect(b0, a0, b3, a3, 0.0, 0.0, distance, 0.0))
+ if (Line2D.linesIntersect(b0, a0, b3, a3, EPSILON, 0.0, distance, 0.0))
nCrossings++;
}
else
{
- if (Line2D.linesIntersect(a0, b0, a3, b3, 0.0, 0.0, 0.0, distance))
+ if (Line2D.linesIntersect(a0, b0, a3, b3, 0.0, EPSILON, 0.0, distance))
nCrossings++;
}
diff --git a/libjava/java/awt/geom/Ellipse2D.java b/libjava/java/awt/geom/Ellipse2D.java
index 223a1930991..bd64adf1e3a 100644
--- a/libjava/java/awt/geom/Ellipse2D.java
+++ b/libjava/java/awt/geom/Ellipse2D.java
@@ -1,5 +1,5 @@
/* Ellipse2D.java -- represents an ellipse in 2-D space
- Copyright (C) 2000, 2002 Free Software Foundation
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -37,58 +37,153 @@ exception statement from your version. */
package java.awt.geom;
+
/**
+ * Ellipse2D is the shape of an ellipse.
+ * <BR>
+ * <img src="doc-files/Ellipse-1.png" width="347" height="221"
+ * alt="A drawing of an ellipse" /><BR>
+ * The ellipse is defined by it's bounding box (shown in red),
+ * and is defined by the implicit curve:<BR>
+ * <blockquote>(<i>x</i>/<i>a</i>)<sup>2</sup> +
+ * (<i>y</i>/<i>b</i>)<sup>2</sup> = 1<BR><BR>
+ *
* @author Tom Tromey <tromey@cygnus.com>
* @author Eric Blake <ebb9@email.byu.edu>
+ *
* @since 1.2
- * @status still needs documentation
*/
public abstract class Ellipse2D extends RectangularShape
{
+ /**
+ * Ellipse2D is defined as abstract.
+ * Implementing classes are Ellipse2D.Float and Ellipse2D.Double.
+ */
protected Ellipse2D()
{
}
+ /**
+ * Determines if a point is contained within the ellipse. <P>
+ * @param x - x coordinate of the point.
+ * @param y - y coordinate of the point.
+ * @return true if the point is within the ellipse, false otherwise.
+ */
public boolean contains(double x, double y)
{
double rx = getWidth() / 2;
double ry = getHeight() / 2;
- double tx = (x - getCenterX()) / rx;
- double ty = (y - getCenterY()) / ry;
- return tx * tx + ty * ty <= 1.0;
+ double tx = (x - (getX() + rx)) / rx;
+ double ty = (y - (getY() + ry)) / ry;
+ return tx * tx + ty * ty < 1.0;
}
+ /**
+ * Determines if a rectangle is completely contained within the
+ * ellipse. <P>
+ * @param x - x coordinate of the upper-left corner of the rectangle
+ * @param y - y coordinate of the upper-left corner of the rectangle
+ * @param w - width of the rectangle
+ * @param h - height of the rectangle
+ * @return true if the rectangle is completely contained, false otherwise.
+ */
public boolean contains(double x, double y, double w, double h)
{
double x2 = x + w;
double y2 = y + h;
- return (contains(x, y) && contains(x, y2)
- && contains(x2, y) && contains(x2, y2));
+ return (contains(x, y) && contains(x, y2) && contains(x2, y)
+ && contains(x2, y2));
}
+ /**
+ * Returns a PathIterator object corresponding to the ellipse.<P>
+ *
+ * Note: An ellipse cannot be represented exactly in PathIterator
+ * segments, the outline is thefore approximated with cubic
+ * Bezier segments.
+ *
+ * @param at an optional transform.
+ * @return A path iterator.
+ */
public PathIterator getPathIterator(AffineTransform at)
{
// An ellipse is just a complete arc.
return new Arc2D.ArcIterator(this, at);
}
+ /**
+ * Determines if a rectangle intersects any part of the ellipse.<P>
+ * @param x - x coordinate of the upper-left corner of the rectangle
+ * @param y - y coordinate of the upper-left corner of the rectangle
+ * @param w - width of the rectangle
+ * @param h - height of the rectangle
+ * @return true if the rectangle intersects the ellipse, false otherwise.
+ */
public boolean intersects(double x, double y, double w, double h)
{
- // fixme
+ Rectangle2D r = new Rectangle2D.Double(x, y, w, h);
+ if (! r.intersects(getX(), getY(), getWidth(), getHeight()))
+ return false;
+
+ if (contains(x, y) || contains(x, y + h) || contains(x + w, y)
+ || contains(x + w, y + h))
+ return true;
+
+ Line2D l1 = new Line2D.Double(getX(), getY() + (getHeight() / 2),
+ getX() + getWidth(),
+ getY() + (getHeight() / 2));
+ Line2D l2 = new Line2D.Double(getX() + (getWidth() / 2), getY(),
+ getX() + (getWidth() / 2),
+ getY() + getHeight());
+
+ if (l1.intersects(r) || l2.intersects(r))
+ return true;
+
return false;
}
+ /**
+ * An {@link Ellipse2D} that stores its coordinates using <code>double</code>
+ * primitives.
+ */
public static class Double extends Ellipse2D
{
+ /**
+ * The height of the ellipse.
+ */
public double height;
+
+ /**
+ * The width of the ellipse.
+ */
public double width;
+
+ /**
+ * The upper-left x coordinate of the bounding-box
+ */
public double x;
+
+ /**
+ * The upper-left y coordinate of the bounding-box
+ */
public double y;
+ /**
+ * Creates a new Ellipse2D with an upper-left coordinate of (0,0)
+ * and a zero size.
+ */
public Double()
{
}
+ /**
+ * Creates a new Ellipse2D within a given rectangle
+ * using double-precision coordinates.<P>
+ * @param x - x coordinate of the upper-left of the bounding rectangle
+ * @param y - y coordinate of the upper-left of the bounding rectangle
+ * @param w - width of the ellipse
+ * @param h - height of the ellipse
+ */
public Double(double x, double y, double w, double h)
{
this.x = x;
@@ -97,36 +192,72 @@ public abstract class Ellipse2D extends RectangularShape
width = w;
}
+ /**
+ * Returns the bounding-box of the ellipse.
+ * @return The bounding box.
+ */
public Rectangle2D getBounds2D()
{
return new Rectangle2D.Double(x, y, width, height);
}
+ /**
+ * Returns the height of the ellipse.
+ * @return The height of the ellipse.
+ */
public double getHeight()
{
return height;
}
+ /**
+ * Returns the width of the ellipse.
+ * @return The width of the ellipse.
+ */
public double getWidth()
{
return width;
}
+ /**
+ * Returns x coordinate of the upper-left corner of
+ * the ellipse's bounding-box.
+ * @return The x coordinate.
+ */
public double getX()
{
return x;
}
+ /**
+ * Returns y coordinate of the upper-left corner of
+ * the ellipse's bounding-box.
+ * @return The y coordinate.
+ */
public double getY()
{
return y;
}
+ /**
+ * Returns <code>true</code> if the ellipse encloses no area, and
+ * <code>false</code> otherwise.
+ *
+ * @return A boolean.
+ */
public boolean isEmpty()
{
return height <= 0 || width <= 0;
}
+ /**
+ * Sets the geometry of the ellipse's bounding box.<P>
+ *
+ * @param x - x coordinate of the upper-left of the bounding rectangle
+ * @param y - y coordinate of the upper-left of the bounding rectangle
+ * @param w - width of the ellipse
+ * @param h - height of the ellipse
+ */
public void setFrame(double x, double y, double w, double h)
{
this.x = x;
@@ -136,17 +267,49 @@ public abstract class Ellipse2D extends RectangularShape
}
} // class Double
+ /**
+ * An {@link Ellipse2D} that stores its coordinates using <code>float</code>
+ * primitives.
+ */
public static class Float extends Ellipse2D
{
+ /**
+ * The height of the ellipse.
+ */
public float height;
+
+ /**
+ * The width of the ellipse.
+ */
public float width;
+
+ /**
+ * The upper-left x coordinate of the bounding-box
+ */
public float x;
+
+ /**
+ * The upper-left y coordinate of the bounding-box
+ */
public float y;
+ /**
+ * Creates a new Ellipse2D with an upper-left coordinate of (0,0)
+ * and a zero size.
+ */
public Float()
{
}
+ /**
+ * Creates a new Ellipse2D within a given rectangle
+ * using floating-point precision.<P>
+ * @param x - x coordinate of the upper-left of the bounding rectangle
+ * @param y - y coordinate of the upper-left of the bounding rectangle
+ * @param w - width of the ellipse
+ * @param h - height of the ellipse
+ *
+ */
public Float(float x, float y, float w, float h)
{
this.x = x;
@@ -155,36 +318,72 @@ public abstract class Ellipse2D extends RectangularShape
this.width = w;
}
+ /**
+ * Returns the bounding-box of the ellipse.
+ * @return The bounding box.
+ */
public Rectangle2D getBounds2D()
{
return new Rectangle2D.Float(x, y, width, height);
}
+ /**
+ * Returns the height of the ellipse.
+ * @return The height of the ellipse.
+ */
public double getHeight()
{
return height;
}
+ /**
+ * Returns the width of the ellipse.
+ * @return The width of the ellipse.
+ */
public double getWidth()
{
return width;
}
+ /**
+ * Returns x coordinate of the upper-left corner of
+ * the ellipse's bounding-box.
+ * @return The x coordinate.
+ */
public double getX()
{
return x;
}
+ /**
+ * Returns y coordinate of the upper-left corner of
+ * the ellipse's bounding-box.
+ * @return The y coordinate.
+ */
public double getY()
{
return y;
}
+ /**
+ * Returns <code>true</code> if the ellipse encloses no area, and
+ * <code>false</code> otherwise.
+ *
+ * @return A boolean.
+ */
public boolean isEmpty()
{
return height <= 0 || width <= 0;
}
+ /**
+ * Sets the geometry of the ellipse's bounding box.<P>
+ *
+ * @param x - x coordinate of the upper-left of the bounding rectangle
+ * @param y - y coordinate of the upper-left of the bounding rectangle
+ * @param w - width of the ellipse
+ * @param h - height of the ellipse
+ */
public void setFrame(float x, float y, float w, float h)
{
this.x = x;
@@ -193,6 +392,16 @@ public abstract class Ellipse2D extends RectangularShape
width = w;
}
+ /**
+ * Sets the geometry of the ellipse's bounding box.
+ *
+ * Note: This leads to a loss of precision.<P>
+ *
+ * @param x - x coordinate of the upper-left of the bounding rectangle
+ * @param y - y coordinate of the upper-left of the bounding rectangle
+ * @param w - width of the ellipse
+ * @param h - height of the ellipse
+ */
public void setFrame(double x, double y, double w, double h)
{
this.x = (float) x;
diff --git a/libjava/java/awt/geom/GeneralPath.java b/libjava/java/awt/geom/GeneralPath.java
index 40182eabf7e..0dc9ede2942 100644
--- a/libjava/java/awt/geom/GeneralPath.java
+++ b/libjava/java/awt/geom/GeneralPath.java
@@ -1,39 +1,40 @@
/* GeneralPath.java -- represents a shape built from subpaths
Copyright (C) 2002, 2003, 2004 Free Software Foundation
- 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., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 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. */
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.awt.geom;
@@ -641,7 +642,7 @@ public final class GeneralPath implements Shape, Cloneable
if (transform != null)
transform.transform( /* src */
coords, /* srcOffset */
- pos, /* dest */ coords, /* destOffset */
+ 0, /* dest */ coords, /* destOffset */
0, /* numPoints */ numCoords);
}
return seg;
@@ -777,7 +778,10 @@ public final class GeneralPath implements Shape, Cloneable
/* Get a value which is hopefully small but not insignificant relative
the path. */
- epsilon = ypoints[0] * 1E-9;
+ epsilon = ypoints[0] * 1E-7;
+
+ if(epsilon == 0)
+ epsilon = 1E-7;
pos = 0;
while (pos < index)
@@ -793,11 +797,11 @@ public final class GeneralPath implements Shape, Cloneable
y1 = firsty;
if (y0 == 0.0)
- y0 += epsilon;
+ y0 -= epsilon;
if (y1 == 0.0)
- y1 += epsilon;
- if (Line2D.linesIntersect(x0, y0, x1, y1, 0.0, 0.0, distance,
- 0.0))
+ y1 -= epsilon;
+ if (Line2D.linesIntersect(x0, y0, x1, y1,
+ epsilon, 0.0, distance, 0.0))
windingNumber += (y1 < y0) ? 1 : negative;
cx = firstx;
@@ -814,10 +818,11 @@ public final class GeneralPath implements Shape, Cloneable
y1 = firsty;
if (y0 == 0.0)
- y0 += epsilon;
+ y0 -= epsilon;
if (y1 == 0.0)
- y1 += epsilon;
- if (Line2D.linesIntersect(x0, y0, x1, y1, 0.0, 0.0, distance, 0.0))
+ y1 -= epsilon;
+ if (Line2D.linesIntersect(x0, y0, x1, y1,
+ epsilon, 0.0, distance, 0.0))
windingNumber += (y1 < y0) ? 1 : negative;
cx = firstx;
@@ -832,10 +837,11 @@ public final class GeneralPath implements Shape, Cloneable
y1 = ypoints[pos++] - (float) y;
if (y0 == 0.0)
- y0 += epsilon;
+ y0 -= epsilon;
if (y1 == 0.0)
- y1 += epsilon;
- if (Line2D.linesIntersect(x0, y0, x1, y1, 0.0, 0.0, distance, 0.0))
+ y1 -= epsilon;
+ if (Line2D.linesIntersect(x0, y0, x1, y1,
+ epsilon, 0.0, distance, 0.0))
windingNumber += (y1 < y0) ? 1 : negative;
cx = xpoints[pos - 1] - (float) x;
@@ -854,9 +860,9 @@ public final class GeneralPath implements Shape, Cloneable
&& (y0 * y1 <= 0 || y1 * y2 <= 0))
{
if (y0 == 0.0)
- y0 += epsilon;
+ y0 -= epsilon;
if (y2 == 0.0)
- y2 += epsilon;
+ y2 -= epsilon;
r[0] = y0;
r[1] = 2 * (y1 - y0);
@@ -897,9 +903,9 @@ public final class GeneralPath implements Shape, Cloneable
&& (y0 * y1 <= 0 || y1 * y2 <= 0 || y2 * y3 <= 0))
{
if (y0 == 0.0)
- y0 += epsilon;
+ y0 -= epsilon;
if (y3 == 0.0)
- y3 += epsilon;
+ y3 -= epsilon;
r[0] = y0;
r[1] = 3 * (y1 - y0);
@@ -942,3 +948,4 @@ public final class GeneralPath implements Shape, Cloneable
return (windingNumber);
}
} // class GeneralPath
+
diff --git a/libjava/java/awt/geom/Line2D.java b/libjava/java/awt/geom/Line2D.java
index 15b2ecae80c..05eedcde4b2 100644
--- a/libjava/java/awt/geom/Line2D.java
+++ b/libjava/java/awt/geom/Line2D.java
@@ -48,6 +48,7 @@ import java.util.NoSuchElementException;
*
* @author Tom Tromey <tromey@cygnus.com>
* @author Eric Blake <ebb9@email.byu.edu>
+ * @author David Gilbert
* @since 1.2
* @status updated to 1.4
*/
@@ -235,11 +236,57 @@ public abstract class Line2D implements Shape, Cloneable
}
/**
- * Test if the line segment (x1,y1)-&gt;(x2,y2) intersects the line segment
+ * Computes twice the (signed) area of the triangle defined by the three
+ * points. This method is used for intersection testing.
+ *
+ * @param x1 the x-coordinate of the first point.
+ * @param y1 the y-coordinate of the first point.
+ * @param x2 the x-coordinate of the second point.
+ * @param y2 the y-coordinate of the second point.
+ * @param x3 the x-coordinate of the third point.
+ * @param y3 the y-coordinate of the third point.
+ *
+ * @return Twice the area.
+ */
+ private static double area2(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3)
+ {
+ return (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
+ }
+
+ /**
+ * Returns <code>true</code> if (x3, y3) lies between (x1, y1) and (x2, y2),
+ * and false otherwise, This test assumes that the three points are
+ * collinear, and is used for intersection testing.
+ *
+ * @param x1 the x-coordinate of the first point.
+ * @param y1 the y-coordinate of the first point.
+ * @param x2 the x-coordinate of the second point.
+ * @param y2 the y-coordinate of the second point.
+ * @param x3 the x-coordinate of the third point.
+ * @param y3 the y-coordinate of the third point.
+ *
+ * @return A boolean.
+ */
+ private static boolean between(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3)
+ {
+ if (x1 != x2) {
+ return (x1 <= x3 && x3 <= x2) || (x1 >= x3 && x3 >= x2);
+ }
+ else {
+ return (y1 <= y3 && y3 <= y2) || (y1 >= y3 && y3 >= y2);
+ }
+ }
+
+ /**
+ * Test if the line segment (x1,y1)-&gt;(x2,y2) intersects the line segment
* (x3,y3)-&gt;(x4,y4).
*
* @param x1 the first x coordinate of the first segment
- * @param y1 the first y coordinate of the first segment
+ * @param y1 the first y coordinate of the first segment
* @param x2 the second x coordinate of the first segment
* @param y2 the second y coordinate of the first segment
* @param x3 the first x coordinate of the second segment
@@ -249,16 +296,64 @@ public abstract class Line2D implements Shape, Cloneable
* @return true if the segments intersect
*/
public static boolean linesIntersect(double x1, double y1,
- double x2, double y2,
- double x3, double y3,
- double x4, double y4)
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4)
{
- double beta = (((y1 - y3) * (x4 - x3) + (x1 - x3) * (y4 - y3))
- / ((y2 - y1) * (x4 - x3) + (x2 - x1) * (y4 - y3)));
- if (beta < 0.0 || beta > 1.0)
- return false;
- double alpha = (x1 + beta * (x2 - x1) - x3) / (x4 - x3);
- return alpha >= 0.0 && alpha <= 1.0;
+ double a1, a2, a3, a4;
+
+ // deal with special cases
+ if ((a1 = area2(x1, y1, x2, y2, x3, y3)) == 0.0)
+ {
+ // check if p3 is between p1 and p2 OR
+ // p4 is collinear also AND either between p1 and p2 OR at opposite ends
+ if (between(x1, y1, x2, y2, x3, y3))
+ {
+ return true;
+ }
+ else
+ {
+ if (area2(x1, y1, x2, y2, x4, y4) == 0.0)
+ {
+ return between(x3, y3, x4, y4, x1, y1)
+ || between (x3, y3, x4, y4, x2, y2);
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ else if ((a2 = area2(x1, y1, x2, y2, x4, y4)) == 0.0)
+ {
+ // check if p4 is between p1 and p2 (we already know p3 is not
+ // collinear)
+ return between(x1, y1, x2, y2, x4, y4);
+ }
+
+ if ((a3 = area2(x3, y3, x4, y4, x1, y1)) == 0.0) {
+ // check if p1 is between p3 and p4 OR
+ // p2 is collinear also AND either between p1 and p2 OR at opposite ends
+ if (between(x3, y3, x4, y4, x1, y1)) {
+ return true;
+ }
+ else {
+ if (area2(x3, y3, x4, y4, x2, y2) == 0.0) {
+ return between(x1, y1, x2, y2, x3, y3)
+ || between (x1, y1, x2, y2, x4, y4);
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ else if ((a4 = area2(x3, y3, x4, y4, x2, y2)) == 0.0) {
+ // check if p2 is between p3 and p4 (we already know p1 is not
+ // collinear)
+ return between(x3, y3, x4, y4, x2, y2);
+ }
+ else { // test for regular intersection
+ return ((a1 > 0.0) ^ (a2 > 0.0)) && ((a3 > 0.0) ^ (a4 > 0.0));
+ }
}
/**
diff --git a/libjava/java/awt/geom/PathIterator.java b/libjava/java/awt/geom/PathIterator.java
index 1fb0a46e0ff..8076b5c8353 100644
--- a/libjava/java/awt/geom/PathIterator.java
+++ b/libjava/java/awt/geom/PathIterator.java
@@ -46,8 +46,8 @@ package java.awt.geom;
*
* @author Tom Tromey <tromey@cygnus.com>
* @author Eric Blake <ebb9@email.byu.edu>
- * @see Shape
- * @see Stroke
+ * @see java.awt.Shape
+ * @see java.awt.Stroke
* @see FlatteningPathIterator
* @since 1.2
* @status updated to 1.4
diff --git a/libjava/java/awt/geom/Point2D.java b/libjava/java/awt/geom/Point2D.java
index 48b12f67dbd..d27505fa41d 100644
--- a/libjava/java/awt/geom/Point2D.java
+++ b/libjava/java/awt/geom/Point2D.java
@@ -1,5 +1,5 @@
/* Point2D.java -- generic point in 2-D space
- Copyright (C) 1999, 2000, 2002 Free Software Foundation
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation
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.awt.geom;
/**
@@ -42,8 +43,8 @@ package java.awt.geom;
* representation is left up to the subclass. Point includes two useful
* nested classes, for float and double storage respectively.
*
- * @author Per Bothner <bothner@cygnus.com>
- * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Per Bothner (bothner@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
* @since 1.2
* @status updated to 1.4
*/
@@ -52,7 +53,7 @@ public abstract class Point2D implements Cloneable
/**
* The default constructor.
*
- * @see Point
+ * @see java.awt.Point
* @see Point2D.Float
* @see Point2D.Double
*/
@@ -120,7 +121,7 @@ public abstract class Point2D implements Cloneable
* @param y2 the y coordinate of point 2
* @return the distance from (x1,y1) to (x2,y2)
*/
- static public double distance(double x1, double y1, double x2, double y2)
+ public static double distance(double x1, double y1, double x2, double y2)
{
return Math.sqrt(distanceSq(x1, y1, x2, y2));
}
diff --git a/libjava/java/awt/geom/QuadCurve2D.java b/libjava/java/awt/geom/QuadCurve2D.java
index 0cc9eb46edc..0376d5a01af 100644
--- a/libjava/java/awt/geom/QuadCurve2D.java
+++ b/libjava/java/awt/geom/QuadCurve2D.java
@@ -59,6 +59,7 @@ import java.util.NoSuchElementException;
public abstract class QuadCurve2D implements Shape, Cloneable
{
private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
+ private static final double EPSILON = 1E-10;
/**
* Constructs a new QuadCurve2D. Typical users will want to
@@ -962,12 +963,12 @@ public abstract class QuadCurve2D implements Shape, Cloneable
If this is not done,bad behaviour may result for points on that axis. */
if (a0 == 0.0 || a2 == 0.0)
{
- double small = getFlatness() * (1E-10);
+ double small = getFlatness() * EPSILON;
if (a0 == 0.0)
- a0 += small;
+ a0 -= small;
if (a2 == 0.0)
- a2 += small;
+ a2 -= small;
}
r[0] = a0;
@@ -990,12 +991,12 @@ public abstract class QuadCurve2D implements Shape, Cloneable
if (useYaxis)
{
- if (Line2D.linesIntersect(b0, a0, b2, a2, 0.0, 0.0, distance, 0.0))
+ if (Line2D.linesIntersect(b0, a0, b2, a2, EPSILON, 0.0, distance, 0.0))
nCrossings++;
}
else
{
- if (Line2D.linesIntersect(a0, b0, a2, b2, 0.0, 0.0, 0.0, distance))
+ if (Line2D.linesIntersect(a0, b0, a2, b2, 0.0, EPSILON, 0.0, distance))
nCrossings++;
}
diff --git a/libjava/java/awt/geom/Rectangle2D.java b/libjava/java/awt/geom/Rectangle2D.java
index 8203ca34470..bd1a37c6e09 100644
--- a/libjava/java/awt/geom/Rectangle2D.java
+++ b/libjava/java/awt/geom/Rectangle2D.java
@@ -49,8 +49,8 @@ import java.util.NoSuchElementException;
* in methods like <code>contains</code> or <code>intersects</code> is
* undefined unless the rectangle has positive width and height.
*
- * @author Tom Tromey <tromey@cygnus.com>
- * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Tom Tromey (tromey@cygnus.com)
+ * @author Eric Blake (ebb9@email.byu.edu)
* @since 1.2
* @status updated to 1.4
*/
@@ -71,14 +71,14 @@ public abstract class Rectangle2D extends RectangularShape
public static final int OUT_TOP = 2;
/**
- * The point lies right of the rectangle (p.x > r.maxX).
+ * The point lies right of the rectangle (p.x &gt; r.maxX).
*
* @see #outcode()
*/
public static final int OUT_RIGHT = 4;
/**
- * The point lies below of the rectangle (p.y > r.maxY).
+ * The point lies below of the rectangle (p.y &gt; r.maxY).
*
* @see #outcode()
*/
@@ -335,8 +335,8 @@ public abstract class Rectangle2D extends RectangularShape
* inside the rectangle, a subsequent call to <code>contains</code> may
* return false.
*
- * @param x the X coordinate of the point to add to this rectangle
- * @param y the Y coordinate of the point to add to this rectangle
+ * @param newx the X coordinate of the point to add to this rectangle
+ * @param newy the Y coordinate of the point to add to this rectangle
*/
public void add(double newx, double newy)
{
@@ -368,7 +368,7 @@ public abstract class Rectangle2D extends RectangularShape
*
* @param r the rectangle to add to this rectangle
* @throws NullPointerException if r is null
- * @see #union(Rectangle2D)
+ * @see #union(Rectangle2D, Rectangle2D, Rectangle2D)
*/
public void add(Rectangle2D r)
{
@@ -382,7 +382,7 @@ public abstract class Rectangle2D extends RectangularShape
* safe; modifications to the rectangle do not affect the results of this
* path instance.
*
- * @param transform an optional transform to apply to the iterator
+ * @param at an optional transform to apply to the iterator
* @return a new iterator over the boundary
* @since 1.2
*/
@@ -490,8 +490,8 @@ public abstract class Rectangle2D extends RectangularShape
* path instance. As the rectangle is already flat, the flatness parameter
* is ignored.
*
- * @param transform an optional transform to apply to the iterator
- * @param double the maximum distance for deviation from the real boundary
+ * @param at an optional transform to apply to the iterator
+ * @param flatness the maximum distance for deviation from the real boundary
* @return a new iterator over the boundary
* @since 1.2
*/
@@ -508,7 +508,7 @@ public abstract class Rectangle2D extends RectangularShape
* + 37 * Double.doubleToLongBits(getY())
* + 43 * Double.doubleToLongBits(getWidth())
* + 47 * Double.doubleToLongBits(getHeight());
- * return (int) ((l >> 32) ^ l);
+ * return (int) ((l &gt;&gt; 32) ^ l);
* </pre>
*
* @return the hashcode
@@ -543,7 +543,7 @@ public abstract class Rectangle2D extends RectangularShape
/**
* This class defines a rectangle in <code>double</code> precision.
*
- * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Eric Blake (ebb9@email.byu.edu)
* @since 1.2
* @status updated to 1.4
*/
@@ -747,12 +747,12 @@ public abstract class Rectangle2D extends RectangularShape
return getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width
+ ",h=" + height + ']';
}
- } // class Double
+ }
/**
* This class defines a rectangle in <code>float</code> precision.
*
- * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Eric Blake (ebb9@email.byu.edu)
* @since 1.2
* @status updated to 1.4
*/
@@ -988,5 +988,5 @@ public abstract class Rectangle2D extends RectangularShape
return getClass().getName() + "[x=" + x + ",y=" + y + ",w=" + width
+ ",h=" + height + ']';
}
- } // class Float
-} // class Rectangle2D
+ }
+}
diff --git a/libjava/java/awt/geom/RectangularShape.java b/libjava/java/awt/geom/RectangularShape.java
index 1801e80339d..78e393eafcb 100644
--- a/libjava/java/awt/geom/RectangularShape.java
+++ b/libjava/java/awt/geom/RectangularShape.java
@@ -354,7 +354,7 @@ public abstract class RectangularShape implements Shape, Cloneable
* threadsafe if and only if the iterator returned by
* {@link #getPathIterator(AffineTransform)} is as well.
*
- * @param transform an optional transform to apply to the iterator
+ * @param at an optional transform to apply to the iterator
* @param flatness the desired flatness
* @return a new iterator over the boundary
* @throws IllegalArgumentException if flatness is invalid
diff --git a/libjava/java/awt/im/InputContext.java b/libjava/java/awt/im/InputContext.java
index 2c3c6aaafd1..04e70e313f5 100644
--- a/libjava/java/awt/im/InputContext.java
+++ b/libjava/java/awt/im/InputContext.java
@@ -1,5 +1,5 @@
/* InputContext.java -- provides the context for text input
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,22 +35,24 @@ 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.awt.im;
+import gnu.java.util.EmptyEnumeration;
+
import java.awt.AWTEvent;
import java.awt.AWTException;
import java.awt.Component;
import java.awt.im.spi.InputMethod;
import java.awt.im.spi.InputMethodDescriptor;
import java.io.BufferedReader;
-import java.io.InputStreamReader;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
-import gnu.java.util.EmptyEnumeration;
/**
* Provides a context for controlling input methods and keyboard layouts.
diff --git a/libjava/java/awt/im/spi/InputMethod.java b/libjava/java/awt/im/spi/InputMethod.java
index 8e7e0bccb3f..0e981efb87f 100644
--- a/libjava/java/awt/im/spi/InputMethod.java
+++ b/libjava/java/awt/im/spi/InputMethod.java
@@ -162,7 +162,7 @@ public interface InputMethod
* called on a previous client.</li>
* </ul>
*
- * @param the client window's current bounds, or null
+ * @param bounds the client window's current bounds, or null
*/
void notifyClientWindowChange(Rectangle bounds);
diff --git a/libjava/java/awt/im/spi/InputMethodContext.java b/libjava/java/awt/im/spi/InputMethodContext.java
index 6243ffa34d0..a2ea4759c72 100644
--- a/libjava/java/awt/im/spi/InputMethodContext.java
+++ b/libjava/java/awt/im/spi/InputMethodContext.java
@@ -1,5 +1,5 @@
/* InputMethodContext.java -- communication between an input method and client
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,13 +35,14 @@ 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.awt.im.spi;
-import java.awt.HeadlessException;
import java.awt.Window;
import java.awt.font.TextHitInfo;
import java.awt.im.InputMethodRequests;
import java.text.AttributedCharacterIterator;
+
import javax.swing.JFrame;
/**
@@ -49,7 +50,7 @@ import javax.swing.JFrame;
* and the client component. This should be passed to
* {@link InputMethod#setInputMethodContext(InputMethodContext)}.
*
- * @author Eric Blake <ebb9@email.byu.edu>
+ * @author Eric Blake (ebb9@email.byu.edu)
* @since 1.3
* @status updated to 1.4
*/
diff --git a/libjava/java/awt/image/AffineTransformOp.java b/libjava/java/awt/image/AffineTransformOp.java
index 6219635fa51..1326a61c043 100644
--- a/libjava/java/awt/image/AffineTransformOp.java
+++ b/libjava/java/awt/image/AffineTransformOp.java
@@ -1,6 +1,6 @@
/* AffineTransformOp.java -- This class performs affine
- * transformation between two images or rasters in 2
- * dimensions. Copyright (C) 2004 Free Software Foundation
+ transformation between two images or rasters in 2 dimensions.
+ Copyright (C) 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -38,30 +38,39 @@ exception statement from your version. */
package java.awt.image;
-import java.awt.*;
-import java.awt.Graphics;
import java.awt.Graphics2D;
-import java.awt.geom.*;
-
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
/**
* This class performs affine transformation between two images or
* rasters in 2 dimensions.
*
- * @author Olga Rodimina <rodimina@redhat.com>
+ * @author Olga Rodimina (rodimina@redhat.com)
*/
-
public class AffineTransformOp implements BufferedImageOp, RasterOp
{
- public static final int TYPE_BILINEAR = 0;
public static final int TYPE_NEAREST_NEIGHBOR = 1;
+
+ public static final int TYPE_BILINEAR = 2;
+
+ /**
+ * @since 1.5.0
+ */
+ public static final int TYPE_BICUBIC = 3;
private AffineTransform transform;
private RenderingHints hints;
/**
* Construct AffineTransformOp with the given xform and interpolationType.
- * Interpolation type can be either TYPE_BILINEAR or TYPE_NEAREST_NEIGHBOR.
+ * Interpolation type can be TYPE_BILINEAR, TYPE_BICUBIC or
+ * TYPE_NEAREST_NEIGHBOR.
*
* @param xform AffineTransform that will applied to the source image
* @param interpolationType type of interpolation used
@@ -69,15 +78,23 @@ public class AffineTransformOp implements BufferedImageOp, RasterOp
public AffineTransformOp (AffineTransform xform, int interpolationType)
{
this.transform = xform;
+ if (xform.getDeterminant() == 0)
+ throw new ImagingOpException(null);
- if (interpolationType == 0)
+ switch (interpolationType)
+ {
+ case TYPE_BILINEAR:
hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
-
- else
+ break;
+ case TYPE_BICUBIC:
+ hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
+ RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+ break;
+ default:
hints = new RenderingHints (RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
-
+ }
}
/**
@@ -90,6 +107,8 @@ public class AffineTransformOp implements BufferedImageOp, RasterOp
{
this.transform = xform;
this.hints = hints;
+ if (xform.getDeterminant() == 0)
+ throw new ImagingOpException(null);
}
/**
@@ -149,7 +168,7 @@ public class AffineTransformOp implements BufferedImageOp, RasterOp
* @param dst destination image
* @return transformed source image
*/
- public BufferedImage filter (BufferedImage src, BufferedImage dst)
+ public final BufferedImage filter (BufferedImage src, BufferedImage dst)
{
if (dst == src)
@@ -180,9 +199,99 @@ public class AffineTransformOp implements BufferedImageOp, RasterOp
* @param dst destination raster
* @return transformed raster
*/
- public WritableRaster filter (Raster src, WritableRaster dst)
+ public final WritableRaster filter (Raster src, WritableRaster dst)
{
- throw new UnsupportedOperationException ("not implemented yet");
+ if (dst == src)
+ throw new IllegalArgumentException("src image cannot be the same as"
+ + " the dst image");
+
+ if (dst == null)
+ dst = createCompatibleDestRaster(src);
+
+ if (src.getNumBands() != dst.getNumBands())
+ throw new IllegalArgumentException("src and dst must have same number"
+ + " of bands");
+
+ double[] dpts = new double[dst.getWidth() * 2];
+ double[] pts = new double[dst.getWidth() * 2];
+ for (int x = 0; x < dst.getWidth(); x++)
+ {
+ dpts[2 * x] = x + dst.getMinX();
+ dpts[2 * x + 1] = x;
+ }
+ Rectangle srcbounds = src.getBounds();
+ if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR))
+ {
+ for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
+ {
+ try {
+ transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
+ } catch (NoninvertibleTransformException e) {
+ // Can't happen since the constructor traps this
+ e.printStackTrace();
+ }
+
+ for (int x = 0; x < dst.getWidth(); x++)
+ {
+ if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
+ continue;
+ dst.setDataElements(x + dst.getMinX(), y,
+ src.getDataElements((int)pts[2 * x],
+ (int)pts[2 * x + 1],
+ null));
+ }
+ }
+ }
+ else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR))
+ {
+ double[] tmp = new double[4 * src.getNumBands()];
+ for (int y = dst.getMinY(); y < dst.getMinY() + dst.getHeight(); y++)
+ {
+ try {
+ transform.inverseTransform(dpts, 0, pts, 0, dst.getWidth() * 2);
+ } catch (NoninvertibleTransformException e) {
+ // Can't happen since the constructor traps this
+ e.printStackTrace();
+ }
+
+ for (int x = 0; x < dst.getWidth(); x++)
+ {
+ if (!srcbounds.contains(pts[2 * x], pts[2 * x + 1]))
+ continue;
+ int xx = (int)pts[2 * x];
+ int yy = (int)pts[2 * x + 1];
+ double dx = (pts[2 * x] - xx);
+ double dy = (pts[2 * x + 1] - yy);
+
+ // TODO write this more intelligently
+ if (xx == src.getMinX() + src.getWidth() - 1 ||
+ yy == src.getMinY() + src.getHeight() - 1)
+ {
+ // bottom or right edge
+ Arrays.fill(tmp, 0);
+ src.getPixel(xx, yy, tmp);
+ }
+ else
+ {
+ // Normal case
+ src.getPixels(xx, yy, 2, 2, tmp);
+ for (int b = 0; b < src.getNumBands(); b++)
+ tmp[b] = dx * dy * tmp[b]
+ + (1 - dx) * dy * tmp[b + src.getNumBands()]
+ + dx * (1 - dy) * tmp[b + 2 * src.getNumBands()]
+ + (1 - dx) * (1 - dy) * tmp[b + 3 * src.getNumBands()];
+ }
+ dst.setPixel(x, y, tmp);
+ }
+ }
+ }
+ else
+ {
+ // Bicubic
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ return dst;
}
/**
@@ -192,7 +301,7 @@ public class AffineTransformOp implements BufferedImageOp, RasterOp
* @param src image to be transformed
* @return bounds of the transformed image.
*/
- public Rectangle2D getBounds2D (BufferedImage src)
+ public final Rectangle2D getBounds2D (BufferedImage src)
{
return getBounds2D (src.getRaster());
}
@@ -203,7 +312,7 @@ public class AffineTransformOp implements BufferedImageOp, RasterOp
* @param src raster to be transformed
* @return bounds of the transformed raster.
*/
- public Rectangle2D getBounds2D (Raster src)
+ public final Rectangle2D getBounds2D (Raster src)
{
// determine new size for the transformed raster.
// Need to calculate transformed coordinates of the lower right
@@ -222,7 +331,7 @@ public class AffineTransformOp implements BufferedImageOp, RasterOp
*
* @return interpolation type
*/
- public int getInterpolationType ()
+ public final int getInterpolationType ()
{
if(hints.containsValue (RenderingHints.VALUE_INTERPOLATION_BILINEAR))
return TYPE_BILINEAR;
@@ -243,21 +352,23 @@ public class AffineTransformOp implements BufferedImageOp, RasterOp
return transform.transform (srcPt, dstPt);
}
- /** Returns rendering hints that are used during transformation.
+ /**
+ * Returns rendering hints that are used during transformation.
*
* @return rendering hints
*/
- public RenderingHints getRenderingHints ()
+ public final RenderingHints getRenderingHints ()
{
return hints;
}
- /** Returns transform used in transformation between source and destination
+ /**
+ * Returns transform used in transformation between source and destination
* image.
*
* @return transform
*/
- public AffineTransform getTransform ()
+ public final AffineTransform getTransform ()
{
return transform;
}
diff --git a/libjava/java/awt/image/BandCombineOp.java b/libjava/java/awt/image/BandCombineOp.java
new file mode 100644
index 00000000000..48c61c57026
--- /dev/null
+++ b/libjava/java/awt/image/BandCombineOp.java
@@ -0,0 +1,168 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.awt.image;
+
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Filter Raster pixels by applying a matrix.
+ *
+ * BandCombineOp applies a matrix to each pixel to produce new pixel values.
+ * The width of the matrix must be the same or one more than the number of
+ * bands in the source Raster. If one more, the pixels in the source are
+ * assumed to contain an implicit 1.0 at the end.
+ *
+ * The rows of the matrix are multiplied by the pixel to produce the values
+ * for the destination. Therefore the destination Raster must contain the
+ * same number of bands as the number of rows in the filter matrix.
+ *
+ * @author Jerry Quinn <jlquinn@optonline.net>
+ */
+public class BandCombineOp implements RasterOp
+{
+ private RenderingHints hints;
+ private float[][] matrix;
+
+ /**
+ * Construct a BandCombineOp.
+ *
+ * @param matrix The matrix to filter pixels with.
+ * @param hints Rendering hints to apply. Ignored.
+ */
+ public BandCombineOp(float[][] matrix, RenderingHints hints)
+ {
+ this.matrix = matrix;
+ this.hints = hints;
+ }
+
+ /**
+ * Filter Raster pixels through a matrix.
+ *
+ * Applies the Op matrix to source pixes to produce dest pixels. Each row
+ * of the matrix is multiplied by the src pixel components to produce the
+ * dest pixel. If matrix is one more than the number of bands in the src,
+ * the last element is implicitly multiplied by 1, i.e. added to the sum
+ * for that dest component.
+ *
+ * If dest is null, a suitable Raster is created. This implementation uses
+ * createCompatibleDestRaster.
+ *
+ * @param src The source Raster.
+ * @param dest The destination Raster, or null.
+ * @returns The destination Raster or an allocated Raster.
+ * @see java.awt.image.RasterOp#filter(java.awt.image.Raster,
+ *java.awt.image.WritableRaster)
+ */
+ public WritableRaster filter(Raster src, WritableRaster dest) {
+ if (dest == null)
+ dest = createCompatibleDestRaster(src);
+
+ // Filter the pixels
+ float[] spix = new float[matrix[0].length];
+ float[] dpix = new float[matrix.length];
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ {
+ // In case matrix rows have implicit translation
+ spix[spix.length - 1] = 1.0f;
+ src.getPixel(x, y, spix);
+ for (int i = 0; i < matrix.length; i++)
+ {
+ dpix[i] = 0;
+ for (int j = 0; j < matrix[0].length; j++)
+ dpix[i] += spix[j] * matrix[i][j];
+ }
+ dest.setPixel(x, y, dpix);
+ }
+
+ return dest;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
+ */
+ public Rectangle2D getBounds2D(Raster src)
+ {
+ return src.getBounds();
+ }
+
+ /**
+ * Creates a new WritableRaster that can be used as the destination for this
+ * Op. This implementation creates a Banded Raster with data type FLOAT.
+ * @see
+ *java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
+ */
+ public WritableRaster createCompatibleDestRaster(Raster src)
+ {
+ return Raster.createBandedRaster(DataBuffer.TYPE_FLOAT, src.getWidth(),
+ src.getHeight(), matrix.length,
+ new Point(src.getMinX(), src.getMinY()));
+ }
+
+ /** Return corresponding destination point for source point.
+ *
+ * LookupOp will return the value of src unchanged.
+ * @param src The source point.
+ * @param dst The destination point.
+ * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D,
+ *java.awt.geom.Point2D)
+ */
+ public Point2D getPoint2D(Point2D src, Point2D dst)
+ {
+ if (dst == null) return (Point2D)src.clone();
+ dst.setLocation(src);
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getRenderingHints()
+ */
+ public RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ /** Return the matrix for this Op. */
+ public float[][] getMatrix()
+ {
+ return matrix;
+ }
+
+}
diff --git a/libjava/java/awt/image/BandedSampleModel.java b/libjava/java/awt/image/BandedSampleModel.java
new file mode 100644
index 00000000000..93252d9cce6
--- /dev/null
+++ b/libjava/java/awt/image/BandedSampleModel.java
@@ -0,0 +1,537 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.awt.image;
+
+/**
+ * MultiPixelPackedSampleModel provides a single band model that supports
+ * multiple pixels in a single unit. Pixels have 2^n bits and 2^k pixels fit
+ * per data element.
+ *
+ * @author Jerry Quinn <jlquinn@optonline.net>
+ */
+public final class BandedSampleModel extends ComponentSampleModel
+{
+ private int[] bitMasks;
+ private int[] bitOffsets;
+ private int[] sampleSize;
+ private int dataBitOffset;
+ private int elemBits;
+ private int numberOfBits;
+ private int numElems;
+
+ public BandedSampleModel(int dataType, int w, int h, int numBands)
+ {
+ super(dataType, w, h, 1, w, new int[numBands]);
+ }
+
+ public BandedSampleModel(int dataType, int w, int h, int scanlineStride,
+ int[] bankIndices, int[] bandOffsets)
+ {
+ super(dataType, w, h, 1, scanlineStride, bankIndices, bandOffsets);
+ }
+
+ public SampleModel createCompatibleSampleModel(int w, int h)
+ {
+ // NOTE: blackdown 1.4.1 sets all offsets to 0. Sun's 1.4.2 docs
+ // disagree.
+
+ // Compress offsets so minimum is 0, others w*scanlineStride
+ int[] newoffsets = new int[bandOffsets.length];
+ int[] order = new int[bandOffsets.length];
+ for (int i=0; i < bandOffsets.length; i++)
+ order[i] = i;
+ // FIXME: This is N^2, but not a big issue, unless there's a lot of
+ // bands...
+ for (int i=0; i < bandOffsets.length; i++)
+ for (int j=i+1; j < bandOffsets.length; i++)
+ if (bankIndices[order[i]] > bankIndices[order[j]]
+ || (bankIndices[order[i]] == bankIndices[order[j]]
+ && bandOffsets[order[i]] > bandOffsets[order[j]]))
+ {
+ int t = order[i]; order[i] = order[j]; order[j] = t;
+ }
+ int bank = 0;
+ int offset = 0;
+ for (int i=0; i < bandOffsets.length; i++)
+ {
+ if (bankIndices[order[i]] != bank)
+ {
+ bank = bankIndices[order[i]];
+ offset = 0;
+ }
+ newoffsets[order[i]] = offset;
+ offset += w * scanlineStride;
+ }
+
+ return new BandedSampleModel(dataType, w, h, scanlineStride, bankIndices, newoffsets);
+ }
+
+
+ public SampleModel createSubsetSampleModel(int[] bands)
+ {
+ int[] newoff = new int[bands.length];
+ int[] newbanks = new int[bands.length];
+ for (int i=0; i < bands.length; i++)
+ {
+ int b = bands[i];
+ newoff[i] = bandOffsets[b];
+ newbanks[i] = bankIndices[b];
+ }
+
+ if (bands.length > bankIndices.length)
+ throw new
+ RasterFormatException("BandedSampleModel createSubsetSampleModel too"
+ +" many bands");
+
+ return new BandedSampleModel(dataType, width, height, scanlineStride,
+ newbanks, newoff);
+ }
+
+ /**
+ * Extract all samples of one pixel and return in an array of transfer type.
+ *
+ * Extracts the pixel at x, y from data and stores samples into the array
+ * obj. If obj is null, a new array of getTransferType() is created.
+ *
+ * @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param obj The primitive array to store the pixels into or null to force creation.
+ * @param data The DataBuffer that is the source of the pixel data.
+ * @return The primitive array containing the pixel data.
+ * @see java.awt.image.SampleModel#getDataElements(int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public Object getDataElements(int x, int y, Object obj,
+ DataBuffer data)
+ {
+ int pixel = getSample(x, y, 0, data);
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ byte[] b = (byte[])obj;
+ if (b == null) b = new byte[numBands];
+ for (int i=0; i < numBands; i++)
+ b[i] = (byte)getSample(x, y, i, data);
+ return b;
+ }
+ case DataBuffer.TYPE_SHORT:
+ case DataBuffer.TYPE_USHORT:
+ {
+ short[] b = (short[])obj;
+ if (b == null) b = new short[numBands];
+ for (int i=0; i < numBands; i++)
+ b[i] = (short)getSample(x, y, i, data);
+ return b;
+ }
+ case DataBuffer.TYPE_INT:
+ {
+ int[] b = (int[])obj;
+ if (b == null) b = new int[numBands];
+ for (int i=0; i < numBands; i++)
+ b[i] = getSample(x, y, i, data);
+ return b;
+ }
+ case DataBuffer.TYPE_FLOAT:
+ {
+ float[] b = (float[])obj;
+ if (b == null) b = new float[numBands];
+ for (int i=0; i < numBands; i++)
+ b[i] = getSampleFloat(x, y, i, data);
+ return b;
+ }
+ case DataBuffer.TYPE_DOUBLE:
+ {
+ double[] b = (double[])obj;
+ if (b == null) b = new double[numBands];
+ for (int i=0; i < numBands; i++)
+ b[i] = getSample(x, y, i, data);
+ return b;
+ }
+
+ default:
+ // Seems like the only sensible thing to do.
+ throw new ClassCastException();
+ }
+ }
+
+ public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ if (iArray == null) iArray = new int[numBands];
+ for (int i=0; i < numBands; i++)
+ iArray[i] = getSample(x, y, 0, data);
+
+ return iArray;
+ }
+
+ /**
+ * Copy pixels from a region into an array.
+ *
+ * Copies the samples of the pixels in the rectangle starting at x, y that
+ * is w pixels wide and h scanlines high. When there is more than one band,
+ * the samples stored in order before the next pixel. This ordering isn't
+ * well specified in Sun's docs as of 1.4.2.
+ *
+ * If iArray is null, a new array is allocated, filled, and returned.
+ *
+ * @param x The x-coordinate of the pixel rectangle to store in
+ * <code>iArray</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in
+ * <code>iArray</code>.
+ * @param w The width in pixels of the rectangle.
+ * @param h The height in pixels of the rectangle.
+ * @param iArray The int array to store the pixels into or null to force
+ * creation.
+ * @param data The DataBuffer that is the source of the pixel data.
+ * @return The primitive array containing the pixel data.
+ */
+ public int[] getPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ if (iArray == null) iArray = new int[w*h*numBands];
+ int outOffset = 0;
+ for (y=0; y<h; y++)
+ {
+ for (x=0; x<w;)
+ {
+ for (int b=0; b < numBands; b++)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + x;
+ iArray[outOffset++] =
+ data.getElem(bankIndices[b], offset);
+ }
+ }
+ }
+ return iArray;
+ }
+
+ public int getSample(int x, int y, int b, DataBuffer data)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + x;
+ return data.getElem(bankIndices[b], offset);
+ }
+
+ public float getSampleFloat(int x, int y, int b, DataBuffer data)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + x;
+ return data.getElemFloat(bankIndices[b], offset);
+ }
+
+ public double getSampleDouble(int x, int y, int b, DataBuffer data)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + x;
+ return data.getElemDouble(bankIndices[b], offset);
+ }
+
+ /**
+ * Copy one band's samples from a region into an array.
+ *
+ * Copies from one band the samples of the pixels in the rectangle starting
+ * at x, y that is w pixels wide and h scanlines high.
+ *
+ * If iArray is null, a new array is allocated, filled, and returned.
+ *
+ * @param x The x-coordinate of the pixel rectangle to store in
+ * <code>iArray</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in
+ * <code>iArray</code>.
+ * @param w The width in pixels of the rectangle.
+ * @param h The height in pixels of the rectangle.
+ * @param b The band to retrieve.
+ * @param iArray The int array to store the pixels into or null to force
+ * creation.
+ * @param data The DataBuffer that is the source of the pixel data.
+ * @return The primitive array containing the pixel data.
+ */
+ public int[] getSamples(int x, int y, int w, int h, int b, int[] iArray,
+ DataBuffer data)
+ {
+ if (iArray == null) iArray = new int[w*h];
+ int outOffset = 0;
+ for (y=0; y<h; y++)
+ {
+ for (x=0; x<w;)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + x;
+ iArray[outOffset++] =
+ data.getElem(bankIndices[b], offset);
+ }
+ }
+ return iArray;
+ }
+
+
+ /**
+ * Set the pixel at x, y to the value in the first element of the primitive
+ * array obj.
+ *
+ * @param x The x-coordinate of the data elements in <code>obj</code>.
+ * @param y The y-coordinate of the data elements in <code>obj</code>.
+ * @param obj The primitive array containing the data elements to set.
+ * @param data The DataBuffer to store the data elements into.
+ * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public void setDataElements(int x, int y, Object obj, DataBuffer data)
+ {
+ int transferType = getTransferType();
+ if (getTransferType() != data.getDataType())
+ {
+ throw new IllegalArgumentException("transfer type ("+
+ getTransferType()+"), "+
+ "does not match data "+
+ "buffer type (" +
+ data.getDataType() +
+ ").");
+ }
+
+ int offset = y * scanlineStride + x;
+
+ try
+ {
+ switch (transferType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ DataBufferByte out = (DataBufferByte) data;
+ byte[] in = (byte[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
+ return;
+ }
+ case DataBuffer.TYPE_SHORT:
+ {
+ DataBufferShort out = (DataBufferShort) data;
+ short[] in = (short[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
+ return;
+ }
+ case DataBuffer.TYPE_USHORT:
+ {
+ DataBufferUShort out = (DataBufferUShort) data;
+ short[] in = (short[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
+ return;
+ }
+ case DataBuffer.TYPE_INT:
+ {
+ DataBufferInt out = (DataBufferInt) data;
+ int[] in = (int[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
+ return;
+ }
+ case DataBuffer.TYPE_FLOAT:
+ {
+ DataBufferFloat out = (DataBufferFloat) data;
+ float[] in = (float[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
+ return;
+ }
+ case DataBuffer.TYPE_DOUBLE:
+ {
+ DataBufferDouble out = (DataBufferDouble) data;
+ double[] in = (double[]) obj;
+ for (int i=0; i < numBands; i++)
+ out.getData(bankIndices[i])[offset + bandOffsets[i]] = in[0];
+ return;
+ }
+ default:
+ throw new ClassCastException("Unsupported data type");
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException aioobe)
+ {
+ String msg = "While writing data elements" +
+ ", x="+x+", y="+y+
+ ", width="+width+", height="+height+
+ ", scanlineStride="+scanlineStride+
+ ", offset="+offset+
+ ", data.getSize()="+data.getSize()+
+ ", data.getOffset()="+data.getOffset()+
+ ": " +
+ aioobe;
+ throw new ArrayIndexOutOfBoundsException(msg);
+ }
+ }
+
+ public void setPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ for (int b=0; b < numBands; b++)
+ data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x,
+ iArray[b]);
+ }
+
+ public void setPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ int inOffset = 0;
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = y * scanlineStride + (x + ww);
+ for (int b=0; b < numBands; b++)
+ data.setElem(bankIndices[b], bandOffsets[b] + offset,
+ iArray[inOffset++]);
+ }
+ y++;
+ }
+ }
+
+ public void setSample(int x, int y, int b, int s, DataBuffer data)
+ {
+ data.setElem(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
+ }
+
+ public void setSample(int x, int y, int b, float s, DataBuffer data)
+ {
+ data.setElemFloat(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
+ }
+
+ public void setSample(int x, int y, int b, double s, DataBuffer data)
+ {
+ data.setElemDouble(bankIndices[b], bandOffsets[b] + y * scanlineStride + x, s);
+ }
+
+ public void setSamples(int x, int y, int w, int h, int b, int[] iArray,
+ DataBuffer data)
+ {
+ int inOffset = 0;
+
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ DataBufferByte out = (DataBufferByte) data;
+ byte[] bank = out.getData(bankIndices[b]);
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
+ bank[offset] = (byte)iArray[inOffset++];
+ }
+ y++;
+ }
+ return;
+ }
+ case DataBuffer.TYPE_SHORT:
+ {
+ DataBufferShort out = (DataBufferShort) data;
+ short[] bank = out.getData(bankIndices[b]);
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
+ bank[offset] = (short)iArray[inOffset++];
+ }
+ y++;
+ }
+ return;
+ }
+ case DataBuffer.TYPE_USHORT:
+ {
+ DataBufferShort out = (DataBufferShort) data;
+ short[] bank = out.getData(bankIndices[b]);
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
+ bank[offset] = (short)iArray[inOffset++];
+ }
+ y++;
+ }
+ return;
+ }
+ case DataBuffer.TYPE_INT:
+ {
+ DataBufferInt out = (DataBufferInt) data;
+ int[] bank = out.getData(bankIndices[b]);
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
+ bank[offset] = iArray[inOffset++];
+ }
+ y++;
+ }
+ return;
+ }
+ case DataBuffer.TYPE_FLOAT:
+ case DataBuffer.TYPE_DOUBLE:
+ break;
+ default:
+ throw new ClassCastException("Unsupported data type");
+ }
+
+ // Default implementation probably slower for float and double
+ for (int hh = 0; hh < h; hh++)
+ {
+ for (int ww = 0; ww < w; ww++)
+ {
+ int offset = bandOffsets[b] + y * scanlineStride + (x + ww);
+ data.setElem(bankIndices[b], offset, iArray[inOffset++]);
+ }
+ y++;
+ }
+ }
+
+ /**
+ * Creates a String with some information about this SampleModel.
+ * @return A String describing this SampleModel.
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ StringBuffer result = new StringBuffer();
+ result.append(getClass().getName());
+ result.append("[");
+ result.append("scanlineStride=").append(scanlineStride);
+ for(int i=0; i < bitMasks.length; i+=1)
+ {
+ result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
+ }
+
+ result.append("]");
+ return result.toString();
+ }
+}
diff --git a/libjava/java/awt/image/BufferedImage.java b/libjava/java/awt/image/BufferedImage.java
index b18779af146..723eeeb77d8 100644
--- a/libjava/java/awt/image/BufferedImage.java
+++ b/libjava/java/awt/image/BufferedImage.java
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000, 2002, 2003 Free Software Foundation
+/* BufferedImage.java --
+ Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -37,6 +38,8 @@ exception statement from your version. */
package java.awt.image;
+import gnu.java.awt.ComponentDataBlitOp;
+
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
@@ -45,11 +48,10 @@ import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
-import java.util.Hashtable;
-import java.util.Vector;
import java.util.HashSet;
+import java.util.Hashtable;
import java.util.Iterator;
-import gnu.java.awt.ComponentDataBlitOp;
+import java.util.Vector;
/**
* A buffered image always starts at coordinates (0, 0).
@@ -59,7 +61,7 @@ import gnu.java.awt.ComponentDataBlitOp;
* height of the image. This tile is always considered to be checked
* out.
*
- * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
*/
public class BufferedImage extends Image
implements WritableRenderedImage
@@ -79,20 +81,20 @@ public class BufferedImage extends Image
TYPE_BYTE_BINARY = 12,
TYPE_BYTE_INDEXED = 13;
- final static int[] bits3 = { 8, 8, 8 };
- final static int[] bits4 = { 8, 8, 8 };
- final static int[] bits1byte = { 8 };
- final static int[] bits1ushort = { 16 };
+ static final int[] bits3 = { 8, 8, 8 };
+ static final int[] bits4 = { 8, 8, 8 };
+ static final int[] bits1byte = { 8 };
+ static final int[] bits1ushort = { 16 };
- final static int[] masks_int = { 0x00ff0000,
+ static final int[] masks_int = { 0x00ff0000,
0x0000ff00,
0x000000ff,
DataBuffer.TYPE_INT };
- final static int[] masks_565 = { 0xf800,
+ static final int[] masks_565 = { 0xf800,
0x07e0,
0x001f,
DataBuffer.TYPE_USHORT};
- final static int[] masks_555 = { 0x7c00,
+ static final int[] masks_555 = { 0x7c00,
0x03e0,
0x001f,
DataBuffer.TYPE_USHORT};
diff --git a/libjava/java/awt/image/BufferedImageFilter.java b/libjava/java/awt/image/BufferedImageFilter.java
new file mode 100644
index 00000000000..8fa7d473f12
--- /dev/null
+++ b/libjava/java/awt/image/BufferedImageFilter.java
@@ -0,0 +1,110 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.awt.image;
+
+import java.awt.Point;
+
+/**
+ * The BufferedImageFilter class wraps BufferedImageOp objects in a Filter.
+ *
+ * When pixels are pushed through the filter, we create a BufferedImage,
+ * apply the BufferedImageOp, and pass the filtered pixels to the base class.
+ *
+ * @author jlquinn@optonline.net
+ */
+public class BufferedImageFilter extends ImageFilter implements Cloneable
+{
+ private BufferedImageOp op;
+
+ /**
+ *
+ */
+ public BufferedImageFilter(BufferedImageOp op)
+ {
+ super();
+ if (op == null)
+ throw new NullPointerException("BufferedImageFilter null"
+ + " op in constructor");
+ this.op = op;
+ }
+
+ /**
+ * @return Returns the contained BufferedImageOp.
+ */
+ public BufferedImageOp getBufferedImageOp()
+ {
+ return op;
+ }
+
+ // FIXME: Definitely not sure this is the right thing. I'm not sure how to
+ // create a compatible sample model that incorporates scansize != w. I
+ // asume off is handled by the db itself.
+ public void setPixels(int x, int y, int w, int h, ColorModel model,
+ byte[] pixels, int off, int scansize)
+ {
+ // Create an input BufferedImage
+ DataBufferByte db = new DataBufferByte(pixels, scansize * h + off, off);
+ SampleModel sm = model.createCompatibleSampleModel(scansize, h);
+ WritableRaster wr = new WritableRaster(sm, db, new Point(0, 0));
+ BufferedImage in =
+ new BufferedImage(model, wr, model.isAlphaPremultiplied(), null);
+ BufferedImage out = op.createCompatibleDestImage(in, model);
+ op.filter(in, out);
+ DataBuffer dbout = out.getRaster().getDataBuffer();
+ super.setPixels(0, 0, w, h, model, ((DataBufferByte)dbout).getData(), 0,
+ scansize);
+ }
+
+ // FIXME: Definitely not sure this is the right thing. I'm not sure how
+ // to create a compatible sample model that incorporates
+ // scansize != w. I asume off is handled by the db itself.
+ public void setPixels(int x, int y, int w, int h, ColorModel model,
+ int[] pixels, int off, int scansize)
+ {
+ // Create an input BufferedImage
+ DataBufferInt db = new DataBufferInt(pixels, scansize * h + off, off);
+ SampleModel sm = model.createCompatibleSampleModel(scansize, h);
+ WritableRaster wr = new WritableRaster(sm, db, new Point(0, 0));
+ BufferedImage in =
+ new BufferedImage(model, wr, model.isAlphaPremultiplied(), null);
+ BufferedImage out = op.createCompatibleDestImage(in, model);
+ op.filter(in, out);
+ DataBuffer dbout = out.getRaster().getDataBuffer();
+ super.setPixels(0, 0, w, h, model, ((DataBufferInt)dbout).getData(), 0,
+ scansize);
+ }
+}
diff --git a/libjava/java/awt/image/ByteLookupTable.java b/libjava/java/awt/image/ByteLookupTable.java
index 572f6e9212d..f0221915a71 100644
--- a/libjava/java/awt/image/ByteLookupTable.java
+++ b/libjava/java/awt/image/ByteLookupTable.java
@@ -61,7 +61,7 @@ public class ByteLookupTable extends LookupTable
*
* @param offset Offset to be subtracted.
* @param data Array of lookup tables.
- * @exception IllegalArgumentException if offset < 0 or data.length < 1.
+ * @exception IllegalArgumentException if offset &lt; 0 or data.length &lt; 1.
*/
public ByteLookupTable(int offset, byte[][] data)
throws IllegalArgumentException
@@ -78,7 +78,7 @@ public class ByteLookupTable extends LookupTable
*
* @param offset Offset to be subtracted.
* @param data Lookup table for all components.
- * @exception IllegalArgumentException if offset < 0.
+ * @exception IllegalArgumentException if offset &lt; 0.
*/
public ByteLookupTable(int offset, byte[] data)
throws IllegalArgumentException
@@ -87,7 +87,11 @@ public class ByteLookupTable extends LookupTable
this.data = new byte[][] {data};
}
- /** Return the lookup tables. */
+ /**
+ * Return the lookup tables.
+ *
+ * @return the tables
+ */
public final byte[][] getTable()
{
return data;
@@ -107,14 +111,14 @@ public class ByteLookupTable extends LookupTable
* translation arrays.
*
* @param src Component values of a pixel.
- * @param dest Destination array for values, or null.
+ * @param dst Destination array for values, or null.
* @return Translated values for the pixel.
*/
public int[] lookupPixel(int[] src, int[] dst)
throws ArrayIndexOutOfBoundsException
{
if (dst == null)
- dst = new int[numComponents];
+ dst = new int[src.length];
if (data.length == 1)
for (int i=0; i < src.length; i++)
@@ -140,14 +144,14 @@ public class ByteLookupTable extends LookupTable
* translation arrays.
*
* @param src Component values of a pixel.
- * @param dest Destination array for values, or null.
+ * @param dst Destination array for values, or null.
* @return Translated values for the pixel.
*/
public byte[] lookupPixel(byte[] src, byte[] dst)
throws ArrayIndexOutOfBoundsException
{
if (dst == null)
- dst = new byte[numComponents];
+ dst = new byte[src.length];
if (data.length == 1)
for (int i=0; i < src.length; i++)
diff --git a/libjava/java/awt/image/ColorConvertOp.java b/libjava/java/awt/image/ColorConvertOp.java
new file mode 100644
index 00000000000..5fcb37cc7f0
--- /dev/null
+++ b/libjava/java/awt/image/ColorConvertOp.java
@@ -0,0 +1,319 @@
+/* ColorModel.java --
+ Copyright (C) 2004 Free Software Foundation
+
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.awt.image;
+
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.color.ColorSpace;
+import java.awt.color.ICC_ColorSpace;
+import java.awt.color.ICC_Profile;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * ColorConvertOp is a filter for converting an image from one colorspace to
+ * another colorspace. The filter can convert the image through a sequence
+ * of colorspaces or just from source to destination.
+ *
+ * Color conversion is done on the color components without alpha. Thus
+ * if a BufferedImage has alpha premultiplied, this is divided out before
+ * color conversion, and premultiplication applied if the destination
+ * requires it.
+ *
+ * Color rendering and dithering hints may be applied if specified. This is
+ * likely platform-dependent.
+ *
+ * @author jlquinn@optonline.net
+ */
+public class ColorConvertOp implements BufferedImageOp, RasterOp
+{
+ private ColorSpace srccs;
+ private ColorSpace dstcs;
+ private RenderingHints hints;
+ private ICC_Profile[] profiles;
+ private ColorSpace[] spaces;
+ private boolean rasterValid;
+
+
+ /**
+ * Convert BufferedImage through a ColorSpace.
+ *
+ * This filter version is only valid for BufferedImages. The source image
+ * is converted to cspace. If the destination is not null, it is then
+ * converted to the destination colorspace. Normally this filter will only
+ * be used with a null destination.
+ *
+ * @param cspace The target color space.
+ * @param hints Rendering hints to use in conversion, or null.
+ */
+ public ColorConvertOp(ColorSpace cspace, RenderingHints hints)
+ {
+ if (cspace == null)
+ throw new NullPointerException();
+ spaces = new ColorSpace[]{cspace};
+ this.hints = hints;
+ rasterValid = false;
+ }
+
+ public ColorConvertOp(ColorSpace srcCspace, ColorSpace dstCspace,
+ RenderingHints hints)
+ {
+ if (srcCspace == null || dstCspace == null)
+ throw new NullPointerException();
+ spaces = new ColorSpace[]{srcCspace, dstCspace};
+ this.hints = hints;
+ }
+
+ /**
+ * Convert from a source image destination image color space.
+ *
+ * This constructor builds a ColorConvertOp from an array of ICC_Profiles.
+ * The source image will be converted through the sequence of color spaces
+ * defined by the profiles. If the sequence of profiles doesn't give a
+ * well-defined conversion, throws IllegalArgumentException.
+ *
+ * NOTE: Sun's docs don't clearly define what a well-defined conversion is
+ * - or perhaps someone smarter can come along and sort it out.
+ *
+ * For BufferedImages, when the first and last profiles match the
+ * requirements of the source and destination color space respectively, the
+ * corresponding conversion is unnecessary. TODO: code this up. I don't
+ * yet understand how you determine this.
+ *
+ * For Rasters, the first and last profiles must have the same number of
+ * bands as the source and destination Rasters, respectively. If this is
+ * not the case, or there fewer than 2 profiles, an IllegalArgumentException
+ * will be thrown.
+ *
+ * @param profiles
+ * @param hints
+ */
+ public ColorConvertOp(ICC_Profile[] profiles, RenderingHints hints)
+ {
+ if (profiles == null)
+ throw new NullPointerException();
+ this.hints = hints;
+ this.profiles = profiles;
+ // TODO: Determine if this is well-defined.
+ // Create colorspace array with space for src and dest colorspace
+ spaces = new ColorSpace[profiles.length];
+ for (int i = 0; i < profiles.length; i++)
+ spaces[i] = new ICC_ColorSpace(profiles[i]);
+ }
+
+ /** Convert from source image color space to destination image color space.
+ *
+ * Only valid for BufferedImage objects, this Op converts from the source
+ * color space to the destination color space. The destination can't be
+ * null for this operation.
+ *
+ * @param hints Rendering hints to use during conversion, or null.
+ */
+ public ColorConvertOp(RenderingHints hints)
+ {
+ this.hints = hints;
+ srccs = null;
+ dstcs = null;
+ rasterValid = false;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage,
+ java.awt.image.BufferedImage)
+ */
+ public final BufferedImage filter(BufferedImage src, BufferedImage dst)
+ {
+ // TODO: The plan is to create a scanline buffer for intermediate buffers.
+ // For now we just suck it up and create intermediate buffers.
+
+ if (dst == null && spaces.length == 0)
+ throw new IllegalArgumentException();
+
+ // Make sure input isn't premultiplied by alpha
+ if (src.isAlphaPremultiplied())
+ {
+ BufferedImage tmp = createCompatibleDestImage(src, src.getColorModel());
+ copyimage(src, tmp);
+ tmp.coerceData(false);
+ src = tmp;
+ }
+
+ ColorModel scm = src.getColorModel();
+ for (int i = 0; i < spaces.length; i++)
+ {
+ ColorModel cm = scm.cloneColorModel(spaces[i]);
+ BufferedImage tmp = createCompatibleDestImage(src, cm);
+ copyimage(src, tmp);
+ src = tmp;
+ }
+
+ // Intermediate conversions leave result in src
+ if (dst == null)
+ return src;
+
+ // Apply final conversion
+ copyimage(src, dst);
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage, java.awt.image.ColorModel)
+ */
+ public BufferedImage createCompatibleDestImage(BufferedImage src,
+ ColorModel dstCM)
+ {
+ // FIXME: set properties to those in src
+ return new BufferedImage(dstCM,
+ src.getRaster().createCompatibleWritableRaster(),
+ src.isPremultiplied,
+ null);
+ }
+
+ public final ICC_Profile[] getICC_Profiles()
+ {
+ return profiles;
+ }
+
+ /** Return the rendering hints for this op. */
+ public final RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#filter(java.awt.image.Raster, java.awt.image.WritableRaster)
+ */
+ public final WritableRaster filter(Raster src, WritableRaster dest)
+ {
+ if (!rasterValid)
+ throw new IllegalArgumentException();
+
+ // Need to iterate through each color space - there must be at least 2
+ for (int i = 1; i < spaces.length - 1; i++)
+ {
+ // FIXME: this is wrong. tmp needs to have the same number of bands as
+ // spaces[i] has.
+ WritableRaster tmp = createCompatibleDestRaster(src);
+ copyraster(src, spaces[i - 1], tmp, spaces[i]);
+ src = tmp;
+ }
+
+ // FIXME: this is wrong. dst needs to have the same number of bands as
+ // spaces[i] has.
+ if (dest == null)
+ dest = createCompatibleDestRaster(src);
+ copyraster(src, spaces[spaces.length - 2],
+ dest, spaces[spaces.length - 1]);
+
+ return dest;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
+ */
+ public WritableRaster createCompatibleDestRaster(Raster src)
+ {
+ return src.createCompatibleWritableRaster();
+ }
+
+ /** Return corresponding destination point for source point.
+ *
+ * LookupOp will return the value of src unchanged.
+ * @param src The source point.
+ * @param dst The destination point.
+ * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D, java.awt.geom.Point2D)
+ */
+ public final Point2D getPoint2D(Point2D src, Point2D dst)
+ {
+ if (dst == null) return (Point2D)src.clone();
+ dst.setLocation(src);
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
+ */
+ public final Rectangle2D getBounds2D(BufferedImage src)
+ {
+ return src.getRaster().getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
+ */
+ public final Rectangle2D getBounds2D(Raster src)
+ {
+ return src.getBounds();
+ }
+
+ // According to Sven de Marothy, we need to copy the src into the dest
+ // using Graphics2D, in order to use the rendering hints.
+ private void copyimage(BufferedImage src, BufferedImage dst)
+ {
+ Graphics2D gg = dst.createGraphics();
+ gg.setRenderingHints(hints);
+ gg.drawImage(src, 0, 0, null);
+ gg.dispose();
+ }
+
+ private void copyraster(Raster src, ColorSpace scs, WritableRaster dst,
+ ColorSpace dcs)
+ {
+ float[] sbuf = new float[src.getNumBands()];
+
+ if (hints.get(RenderingHints.KEY_COLOR_RENDERING) ==
+ RenderingHints.VALUE_COLOR_RENDER_QUALITY)
+ {
+ // use cie for accuracy
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ dst.setPixel(x, y,
+ dcs.fromCIEXYZ(scs.toCIEXYZ(src.getPixel(x, y, sbuf))));
+ }
+ else
+ {
+ // use rgb - it's probably faster
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ dst.setPixel(x, y,
+ dcs.fromRGB(scs.toRGB(src.getPixel(x, y, sbuf))));
+ }
+ }
+
+}
diff --git a/libjava/java/awt/image/ColorModel.java b/libjava/java/awt/image/ColorModel.java
index 87ab942917a..11615fdadfb 100644
--- a/libjava/java/awt/image/ColorModel.java
+++ b/libjava/java/awt/image/ColorModel.java
@@ -1,4 +1,5 @@
-/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation
+/* ColorModel.java --
+ Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -37,11 +38,13 @@ exception statement from your version. */
package java.awt.image;
-import java.util.Arrays;
+import gnu.java.awt.Buffers;
+
import java.awt.Point;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
-import gnu.java.awt.Buffers;
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
/**
* A color model operates with colors in several formats:
@@ -76,8 +79,8 @@ import gnu.java.awt.Buffers;
*
* </ul>
*
- * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
- * @author C. Brian Jones <cbj@gnu.org>
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
+ * @author C. Brian Jones (cbj@gnu.org)
*/
public abstract class ColorModel implements Transparency
{
@@ -108,7 +111,7 @@ public abstract class ColorModel implements Transparency
* Constructs the default color model. The default color model
* can be obtained by calling <code>getRGBdefault</code> of this
* class.
- * @param b the number of bits wide used for bit size of pixel values
+ * @param bits the number of bits wide used for bit size of pixel values
*/
public ColorModel(int bits)
{
@@ -156,6 +159,32 @@ public abstract class ColorModel implements Transparency
this.transferType = transferType;
}
+ // This is a hook for ColorConvertOp to create a colormodel with
+ // a new colorspace
+ ColorModel cloneColorModel(ColorSpace cspace)
+ {
+ Class cls = this.getClass();
+ ColorModel cm;
+ try {
+ // This constructor will exist.
+ Constructor ctor =
+ cls.getConstructor(new Class[]{int.class, int[].class,
+ ColorSpace.class, boolean.class,
+ boolean.class, int.class, int.class});
+ cm = (ColorModel)ctor.
+ newInstance(new Object[]{new Integer(pixel_bits),
+ bits, cspace, Boolean.valueOf(hasAlpha),
+ Boolean.valueOf(isAlphaPremultiplied),
+ new Integer(transparency),
+ new Integer(transferType)});
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException();
+ }
+ return cm;
+ }
+
public void finalize()
{
// Do nothing here.
@@ -294,7 +323,7 @@ public abstract class ColorModel implements Transparency
* This method is typically overriden in subclasses to provide a
* more efficient implementation.
*
- * @param array of transferType containing a single pixel. The
+ * @param inData array of transferType containing a single pixel. The
* pixel should be encoded in the natural way of the color model.
*/
public int getRed(Object inData)
@@ -508,40 +537,89 @@ public abstract class ColorModel implements Transparency
* <code>(pixel == cm.getDataElement(cm.getComponents(pixel, null,
* 0), 0))</code>.
*
- * This method is typically overriden in subclasses to provide a
- * more efficient implementation.
+ * This method is overriden in subclasses since this abstract class throws
+ * UnsupportedOperationException().
*
- * @param arrays of unnormalized component samples of single
- * pixel. The scale and multiplication state of the samples are
- * according to the color model. Each component sample is stored
- * as a separate element in the array.
+ * @param components Array of unnormalized component samples of single
+ * pixel. The scale and multiplication state of the samples are according
+ * to the color model. Each component sample is stored as a separate element
+ * in the array.
+ * @param offset Position of the first value of the pixel in components.
*
* @return pixel value encoded according to the color model.
*/
public int getDataElement(int[] components, int offset)
{
- // subclasses has to implement this method.
+ // subclasses have to implement this method.
throw new UnsupportedOperationException();
}
+ /**
+ * Converts the normalized component samples from an array to a pixel
+ * value. I.e. composes the pixel from component samples, but does not
+ * perform any color conversion or scaling of the samples.
+ *
+ * This method is typically overriden in subclasses to provide a
+ * more efficient implementation. The method provided by this abstract
+ * class converts the components to unnormalized form and returns
+ * getDataElement(int[], int).
+ *
+ * @param components Array of normalized component samples of single pixel.
+ * The scale and multiplication state of the samples are according to the
+ * color model. Each component sample is stored as a separate element in the
+ * array.
+ * @param offset Position of the first value of the pixel in components.
+ *
+ * @return pixel value encoded according to the color model.
+ * @since 1.4
+ */
public int getDataElement (float[] components, int offset)
{
- // subclasses has to implement this method.
- throw new UnsupportedOperationException();
+ return
+ getDataElement(getUnnormalizedComponents(components, offset, null, 0),
+ 0);
}
public Object getDataElements(int[] components, int offset, Object obj)
{
- // subclasses has to implement this method.
+ // subclasses have to implement this method.
throw new UnsupportedOperationException();
}
- public int getDataElements (float[] components, Object obj)
+ /**
+ * Converts the normalized component samples from an array to an array of
+ * TransferType values. I.e. composes the pixel from component samples, but
+ * does not perform any color conversion or scaling of the samples.
+ *
+ * If obj is null, a new array of TransferType is allocated and returned.
+ * Otherwise the results are stored in obj and obj is returned. If obj is
+ * not long enough, ArrayIndexOutOfBounds is thrown. If obj is not an array
+ * of primitives, ClassCastException is thrown.
+ *
+ * This method is typically overriden in subclasses to provide a
+ * more efficient implementation. The method provided by this abstract
+ * class converts the components to unnormalized form and returns
+ * getDataElement(int[], int, Object).
+ *
+ * @param components Array of normalized component samples of single pixel.
+ * The scale and multiplication state of the samples are according to the
+ * color model. Each component sample is stored as a separate element in the
+ * array.
+ * @param offset Position of the first value of the pixel in components.
+ * @param obj Array of TransferType or null.
+ *
+ * @return pixel value encoded according to the color model.
+ * @throws ArrayIndexOutOfBounds
+ * @throws ClassCastException
+ * @since 1.4
+ */
+ public Object getDataElements(float[] components, int offset, Object obj)
{
- // subclasses has to implement this method.
- throw new UnsupportedOperationException();
+ return
+ getDataElements(getUnnormalizedComponents(components, offset, null, 0),
+ 0, obj);
}
-
+
public boolean equals(Object obj)
{
if (!(obj instanceof ColorModel)) return false;
diff --git a/libjava/java/awt/image/ComponentColorModel.java b/libjava/java/awt/image/ComponentColorModel.java
index 24d8b8ea685..2b065328ee0 100644
--- a/libjava/java/awt/image/ComponentColorModel.java
+++ b/libjava/java/awt/image/ComponentColorModel.java
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000, 2002, 2004 Free Software Foundation
+/* ComponentColorModel.java --
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -37,9 +38,10 @@ exception statement from your version. */
package java.awt.image;
+import gnu.java.awt.Buffers;
+
import java.awt.Point;
import java.awt.color.ColorSpace;
-import gnu.java.awt.Buffers;
public class ComponentColorModel extends ColorModel
{
@@ -60,6 +62,32 @@ public class ComponentColorModel extends ColorModel
transparency, transferType);
}
+ /**
+ * Construct a new ComponentColorModel.
+ *
+ * This constructor makes all bits of each sample significant, so for a
+ * transferType of DataBuffer.BYTE, the bits per sample is 8, etc. If
+ * both hasAlpha and isAlphaPremultiplied are true, color samples are
+ * assumed to be premultiplied by the alpha component. Transparency may be
+ * one of OPAQUE, BITMASK, or TRANSLUCENT.
+ *
+ * @param colorSpace The colorspace for this color model.
+ * @param hasAlpha True if there is an alpha component.
+ * @param isAlphaPremultiplied True if colors are already multiplied by
+ * alpha.
+ * @param transparency The type of alpha values.
+ * @param transferType Data type of pixel sample values.
+ * @since 1.4
+ */
+ public ComponentColorModel(ColorSpace colorSpace,
+ boolean hasAlpha,
+ boolean isAlphaPremultiplied,
+ int transparency, int transferType)
+ {
+ this(colorSpace, null, hasAlpha, isAlphaPremultiplied,
+ transparency, transferType);
+ }
+
public int getRed(int pixel)
{
if (getNumComponents()>1) throw new IllegalArgumentException();
@@ -95,12 +123,6 @@ public class ComponentColorModel extends ColorModel
}
- /* FIXME: Is the values returned from toRGB() in the [0.0, 1.0] or the
- [0.0, 256) range?
-
- we assume it is in the [0.0, 1.0] range along with the
- other color spaces. */
-
/* Note, it's OK to pass a to large array to toRGB(). Extra
elements are ignored. */
diff --git a/libjava/java/awt/image/ComponentSampleModel.java b/libjava/java/awt/image/ComponentSampleModel.java
index c7b08b919e5..0665f406793 100644
--- a/libjava/java/awt/image/ComponentSampleModel.java
+++ b/libjava/java/awt/image/ComponentSampleModel.java
@@ -41,6 +41,21 @@ import gnu.java.awt.Buffers;
/* FIXME: This class does not yet support data type TYPE_SHORT */
/**
+ * ComponentSampleModel supports a flexible organization of pixel samples in
+ * memory, permitting pixel samples to be interleaved by band, by scanline,
+ * and by pixel.
+ *
+ * A DataBuffer for this sample model has K banks of data. Pixels have N
+ * samples, so there are N bands in the DataBuffer. Each band is completely
+ * contained in one bank of data, but a bank may contain more than one band.
+ * Each pixel sample is stored in a single data element.
+ *
+ * Within a bank, each band begins at an offset stored in bandOffsets. The
+ * banks containing the band is given by bankIndices. Within the bank, there
+ * are three dimensions - band, pixel, and scanline. The dimension ordering
+ * is controlled by bandOffset, pixelStride, and scanlineStride, which means
+ * that any combination of interleavings is supported.
+ *
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
*/
public class ComponentSampleModel extends SampleModel
@@ -86,6 +101,7 @@ public class ComponentSampleModel extends SampleModel
this.bandOffsets = bandOffsets;
this.bankIndices = bankIndices;
+ this.numBanks = 0;
for (int b=0; b<bankIndices.length; b++)
this.numBanks = Math.max(this.numBanks, bankIndices[b]+1);
@@ -249,6 +265,18 @@ public class ComponentSampleModel extends SampleModel
}
return outUShort;
+ case DataBuffer.TYPE_SHORT:
+ DataBufferShort inShort = (DataBufferShort) data;
+ short[] outShort = (short[]) obj;
+ if (outShort == null) outShort = new short[numBands];
+
+ for (int b=0; b<numBands; b++)
+ {
+ int dOffset = totalBandDataOffsets[b];
+ outShort[b] = inShort.getData(bankIndices[b])[dOffset];
+ }
+ return outShort;
+
case DataBuffer.TYPE_INT:
DataBufferInt inInt = (DataBufferInt) data;
int[] outInt = (int[]) obj;
@@ -260,8 +288,31 @@ public class ComponentSampleModel extends SampleModel
outInt[b] = inInt.getData(bankIndices[b])[dOffset];
}
return outInt;
-
- // FIXME: Fill in the other possible types.
+
+ case DataBuffer.TYPE_FLOAT:
+ DataBufferFloat inFloat = (DataBufferFloat) data;
+ float[] outFloat = (float[]) obj;
+ if (outFloat == null) outFloat = new float[numBands];
+
+ for (int b=0; b<numBands; b++)
+ {
+ int dOffset = totalBandDataOffsets[b];
+ outFloat[b] = inFloat.getData(bankIndices[b])[dOffset];
+ }
+ return outFloat;
+
+ case DataBuffer.TYPE_DOUBLE:
+ DataBufferDouble inDouble = (DataBufferDouble) data;
+ double[] outDouble = (double[]) obj;
+ if (outDouble == null) outDouble = new double[numBands];
+
+ for (int b=0; b<numBands; b++)
+ {
+ int dOffset = totalBandDataOffsets[b];
+ outDouble[b] = inDouble.getData(bankIndices[b])[dOffset];
+ }
+ return outDouble;
+
default:
throw new IllegalStateException("unknown transfer type " +
getTransferType());
@@ -433,6 +484,16 @@ public class ComponentSampleModel extends SampleModel
return;
}
+ case DataBuffer.TYPE_SHORT:
+ {
+ DataBufferShort out = (DataBufferShort) data;
+ short[] in = (short[]) obj;
+
+ for (int b=0; b<numBands; b++)
+ out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
+
+ return;
+ }
case DataBuffer.TYPE_INT:
{
DataBufferInt out = (DataBufferInt) data;
@@ -443,6 +504,26 @@ public class ComponentSampleModel extends SampleModel
return;
}
+ case DataBuffer.TYPE_FLOAT:
+ {
+ DataBufferFloat out = (DataBufferFloat) data;
+ float[] in = (float[]) obj;
+
+ for (int b=0; b<numBands; b++)
+ out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
+
+ return;
+ }
+ case DataBuffer.TYPE_DOUBLE:
+ {
+ DataBufferDouble out = (DataBufferDouble) data;
+ double[] in = (double[]) obj;
+
+ for (int b=0; b<numBands; b++)
+ out.getData(bankIndices[b])[totalBandDataOffsets[b]] = in[b];
+
+ return;
+ }
default:
throw new UnsupportedOperationException("transfer type not " +
"implemented");
diff --git a/libjava/java/awt/image/ConvolveOp.java b/libjava/java/awt/image/ConvolveOp.java
new file mode 100644
index 00000000000..c793eee1434
--- /dev/null
+++ b/libjava/java/awt/image/ConvolveOp.java
@@ -0,0 +1,341 @@
+/* Copyright (C) 2004 Free Software Foundation -- ConvolveOp
+
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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. */
+
+/*
+ * Created on Nov 1, 2004
+ *
+ * TODO To change the template for this generated file go to
+ * Window - Preferences - Java - Code Style - Code Templates
+ */
+package java.awt.image;
+
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+/**
+ * Convolution filter.
+ *
+ * ConvolveOp convolves the source image with a Kernel to generate a
+ * destination image. This involves multiplying each pixel and its neighbors
+ * with elements in the kernel to compute a new pixel.
+ *
+ * Each band in a Raster is convolved and copied to the destination Raster.
+ *
+ * For BufferedImages, convolution is applied to all components. If the
+ * source is not premultiplied, the data will be premultiplied before
+ * convolving. Premultiplication will be undone if the destination is not
+ * premultiplied. Color conversion will be applied if needed.
+ *
+ * @author jlquinn@optonline.net
+ */
+public class ConvolveOp implements BufferedImageOp, RasterOp
+{
+ /** Edge pixels are set to 0. */
+ public static final int EDGE_ZERO_FILL = 0;
+
+ /** Edge pixels are copied from the source. */
+ public static final int EDGE_NO_OP = 1;
+
+ private Kernel kernel;
+ private int edge;
+ private RenderingHints hints;
+
+ /**
+ * Construct a ConvolveOp.
+ *
+ * The edge condition specifies that pixels outside the area that can be
+ * filtered are either set to 0 or copied from the source image.
+ *
+ * @param kernel The kernel to convolve with.
+ * @param edgeCondition Either EDGE_ZERO_FILL or EDGE_NO_OP.
+ * @param hints Rendering hints for color conversion, or null.
+ */
+ public ConvolveOp(Kernel kernel,
+ int edgeCondition,
+ RenderingHints hints)
+ {
+ this.kernel = kernel;
+ edge = edgeCondition;
+ this.hints = hints;
+ }
+
+ /**
+ * Construct a ConvolveOp.
+ *
+ * The edge condition defaults to EDGE_ZERO_FILL.
+ *
+ * @param kernel The kernel to convolve with.
+ */
+ public ConvolveOp(Kernel kernel)
+ {
+ this.kernel = kernel;
+ edge = EDGE_ZERO_FILL;
+ hints = null;
+ }
+
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage,
+ * java.awt.image.BufferedImage)
+ */
+ public BufferedImage filter(BufferedImage src, BufferedImage dst)
+ {
+ if (src == dst)
+ throw new IllegalArgumentException();
+
+ if (dst == null)
+ dst = createCompatibleDestImage(src, src.getColorModel());
+
+ // Make sure source image is premultiplied
+ BufferedImage src1 = src;
+ if (!src.isPremultiplied)
+ {
+ src1 = createCompatibleDestImage(src, src.getColorModel());
+ src.copyData(src1.getRaster());
+ src1.coerceData(true);
+ }
+
+ BufferedImage dst1 = dst;
+ if (!src.getColorModel().equals(dst.getColorModel()))
+ dst1 = createCompatibleDestImage(src, src.getColorModel());
+
+ filter(src1.getRaster(), dst1.getRaster());
+
+ if (dst1 != dst)
+ {
+ // Convert between color models.
+ // TODO Check that premultiplied alpha is handled correctly here.
+ Graphics2D gg = dst.createGraphics();
+ gg.setRenderingHints(hints);
+ gg.drawImage(dst1, 0, 0, null);
+ gg.dispose();
+ }
+
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see
+ * java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage,
+ * java.awt.image.ColorModel)
+ */
+ public BufferedImage createCompatibleDestImage(BufferedImage src,
+ ColorModel dstCM)
+ {
+ // FIXME: set properties to those in src
+ return new BufferedImage(dstCM,
+ src.getRaster().createCompatibleWritableRaster(),
+ src.isPremultiplied, null);
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getRenderingHints()
+ */
+ public RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ /**
+ * @return The edge condition.
+ */
+ public int getEdgeCondition()
+ {
+ return edge;
+ }
+
+ /**
+ * @return The convolution kernel.
+ */
+ public Kernel getKernel()
+ {
+ return kernel;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#filter(java.awt.image.Raster,
+ * java.awt.image.WritableRaster)
+ */
+ public WritableRaster filter(Raster src, WritableRaster dest) {
+ if (src.numBands != dest.numBands)
+ throw new ImagingOpException(null);
+ if (src == dest)
+ throw new IllegalArgumentException();
+ if (src.getWidth() < kernel.getWidth() ||
+ src.getHeight() < kernel.getHeight())
+ throw new ImagingOpException(null);
+
+ if (dest == null)
+ dest = createCompatibleDestRaster(src);
+
+ // Deal with bottom edge
+ if (edge == EDGE_ZERO_FILL)
+ {
+ float[] zeros = new float[src.getNumBands() * src.getWidth()
+ * (kernel.getYOrigin() - 1)];
+ Arrays.fill(zeros, 0);
+ dest.setPixels(src.getMinX(), src.getMinY(), src.getWidth(),
+ kernel.getYOrigin() - 1, zeros);
+ }
+ else
+ {
+ float[] vals = new float[src.getNumBands() * src.getWidth()
+ * (kernel.getYOrigin() - 1)];
+ src.getPixels(src.getMinX(), src.getMinY(), src.getWidth(),
+ kernel.getYOrigin() - 1, vals);
+ dest.setPixels(src.getMinX(), src.getMinY(), src.getWidth(),
+ kernel.getYOrigin() - 1, vals);
+ }
+
+ // Handle main section
+ float[] kvals = kernel.getKernelData(null);
+
+ float[] tmp = new float[kernel.getWidth() * kernel.getHeight()];
+ for (int y = src.getMinY() + kernel.getYOrigin();
+ y < src.getMinY() + src.getHeight() - kernel.getYOrigin() / 2; y++)
+ {
+ // Handle unfiltered edge pixels at start of line
+ float[] t1 = new float[(kernel.getXOrigin() - 1) * src.getNumBands()];
+ if (edge == EDGE_ZERO_FILL)
+ Arrays.fill(t1, 0);
+ else
+ src.getPixels(src.getMinX(), y, kernel.getXOrigin() - 1, 1, t1);
+ dest.setPixels(src.getMinX(), y, kernel.getXOrigin() - 1, 1, t1);
+
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ {
+ // FIXME: This needs a much more efficient implementation
+ for (int b = 0; b < src.getNumBands(); b++)
+ {
+ float v = 0;
+ src.getSamples(x, y, kernel.getWidth(), kernel.getHeight(), b, tmp);
+ for (int i=0; i < tmp.length; i++)
+ v += tmp[i] * kvals[i];
+ dest.setSample(x, y, b, v);
+ }
+ }
+
+ // Handle unfiltered edge pixels at end of line
+ float[] t2 = new float[(kernel.getWidth() / 2) * src.getNumBands()];
+ if (edge == EDGE_ZERO_FILL)
+ Arrays.fill(t2, 0);
+ else
+ src.getPixels(src.getMinX() + src.getWidth()
+ - (kernel.getWidth() / 2),
+ y, kernel.getWidth() / 2, 1, t2);
+ dest.setPixels(src.getMinX() + src.getWidth() - (kernel.getWidth() / 2),
+ y, kernel.getWidth() / 2, 1, t2);
+ }
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x< src.getWidth() + src.getMinX(); x++)
+ {
+
+ }
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x< src.getWidth() + src.getMinX(); x++)
+ {
+
+ }
+
+ // Handle top edge
+ if (edge == EDGE_ZERO_FILL)
+ {
+ float[] zeros = new float[src.getNumBands() * src.getWidth() *
+ (kernel.getHeight() / 2)];
+ Arrays.fill(zeros, 0);
+ dest.setPixels(src.getMinX(),
+ src.getHeight() + src.getMinY() - (kernel.getHeight() / 2),
+ src.getWidth(), kernel.getHeight() / 2, zeros);
+ }
+ else
+ {
+ float[] vals = new float[src.getNumBands() * src.getWidth() *
+ (kernel.getHeight() / 2)];
+ src.getPixels(src.getMinX(),
+ src.getHeight() + src.getMinY()
+ - (kernel.getHeight() / 2),
+ src.getWidth(), kernel.getHeight() / 2, vals);
+ dest.setPixels(src.getMinX(),
+ src.getHeight() + src.getMinY()
+ - (kernel.getHeight() / 2),
+ src.getWidth(), kernel.getHeight() / 2, vals);
+ }
+
+ return dest;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
+ */
+ public WritableRaster createCompatibleDestRaster(Raster src)
+ {
+ return src.createCompatibleWritableRaster();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
+ */
+ public Rectangle2D getBounds2D(BufferedImage src)
+ {
+ return src.getRaster().getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
+ */
+ public Rectangle2D getBounds2D(Raster src)
+ {
+ return src.getBounds();
+ }
+
+ /** Return corresponding destination point for source point.
+ *
+ * ConvolveOp will return the value of src unchanged.
+ * @param src The source point.
+ * @param dst The destination point.
+ * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D,
+ * java.awt.geom.Point2D)
+ */
+ public Point2D getPoint2D(Point2D src, Point2D dst)
+ {
+ if (dst == null) return (Point2D)src.clone();
+ dst.setLocation(src);
+ return dst;
+ }
+}
diff --git a/libjava/java/awt/image/CropImageFilter.java b/libjava/java/awt/image/CropImageFilter.java
index c9a170b9b3b..a006d26d814 100644
--- a/libjava/java/awt/image/CropImageFilter.java
+++ b/libjava/java/awt/image/CropImageFilter.java
@@ -1,5 +1,5 @@
/* CropImageFilter.java -- Java class for cropping image filter
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,11 +38,10 @@ exception statement from your version. */
package java.awt.image;
-import java.util.Hashtable;
import java.awt.Rectangle;
+import java.util.Hashtable;
/**
- * <br>
* Currently this filter does almost nothing and needs to be implemented.
*
* @author C. Brian Jones (cbj@gnu.org)
diff --git a/libjava/java/awt/image/DataBuffer.java b/libjava/java/awt/image/DataBuffer.java
index 967e1a26c9c..b921953ec28 100644
--- a/libjava/java/awt/image/DataBuffer.java
+++ b/libjava/java/awt/image/DataBuffer.java
@@ -45,12 +45,45 @@ package java.awt.image;
*/
public abstract class DataBuffer
{
+ /**
+ * A constant representng a data type that uses <code>byte</code> primitives
+ * as the storage unit.
+ */
public static final int TYPE_BYTE = 0;
+
+ /**
+ * A constant representng a data type that uses <code>short</code>
+ * primitives as the storage unit.
+ */
public static final int TYPE_USHORT = 1;
+
+ /**
+ * A constant representng a data type that uses <code>short</code>
+ * primitives as the storage unit.
+ */
public static final int TYPE_SHORT = 2;
+
+ /**
+ * A constant representng a data type that uses <code>int</code>
+ * primitives as the storage unit.
+ */
public static final int TYPE_INT = 3;
+
+ /**
+ * A constant representng a data type that uses <code>float</code>
+ * primitives as the storage unit.
+ */
public static final int TYPE_FLOAT = 4;
+
+ /**
+ * A constant representng a data type that uses <code>double</code>
+ * primitives as the storage unit.
+ */
public static final int TYPE_DOUBLE = 5;
+
+ /**
+ * A constant representng an undefined data type.
+ */
public static final int TYPE_UNDEFINED = 32;
/** The type of the data elements stored in the data buffer. */
@@ -68,18 +101,57 @@ public abstract class DataBuffer
/** Offset into each bank. */
protected int[] offsets;
+ /**
+ * Creates a new <code>DataBuffer</code> with the specified data type and
+ * size. The <code>dataType</code> should be one of the constants
+ * {@link #TYPE_BYTE}, {@link #TYPE_SHORT}, {@link #TYPE_USHORT},
+ * {@link #TYPE_INT}, {@link #TYPE_FLOAT} and {@link #TYPE_DOUBLE}.
+ * <p>
+ * The physical (array-based) storage is allocated by a subclass.
+ *
+ * @param dataType the data type.
+ * @param size the number of elements in the buffer.
+ */
protected DataBuffer(int dataType, int size)
{
this.dataType = dataType;
this.size = size;
}
+ /**
+ * Creates a new <code>DataBuffer</code> with the specified data type,
+ * size and number of banks. The <code>dataType</code> should be one of
+ * the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
+ * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
+ * {@link #TYPE_DOUBLE}.
+ * <p>
+ * The physical (array-based) storage is allocated by a subclass.
+ *
+ * @param dataType the data type.
+ * @param size the number of elements in the buffer.
+ * @param numBanks the number of data banks.
+ */
protected DataBuffer(int dataType, int size, int numBanks) {
this(dataType, size);
banks = numBanks;
offsets = new int[numBanks];
}
+ /**
+ * Creates a new <code>DataBuffer</code> with the specified data type,
+ * size and number of banks. An offset (which applies to all banks) is
+ * also specified. The <code>dataType</code> should be one of
+ * the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
+ * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
+ * {@link #TYPE_DOUBLE}.
+ * <p>
+ * The physical (array-based) storage is allocated by a subclass.
+ *
+ * @param dataType the data type.
+ * @param size the number of elements in the buffer.
+ * @param numBanks the number of data banks.
+ * @param offset the offset to the first element for all banks.
+ */
protected DataBuffer(int dataType, int size, int numBanks, int offset) {
this(dataType, size, numBanks);
@@ -88,6 +160,24 @@ public abstract class DataBuffer
this.offset = offset;
}
+ /**
+ * Creates a new <code>DataBuffer</code> with the specified data type,
+ * size and number of banks. An offset (which applies to all banks) is
+ * also specified. The <code>dataType</code> should be one of
+ * the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
+ * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
+ * {@link #TYPE_DOUBLE}.
+ * <p>
+ * The physical (array-based) storage is allocated by a subclass.
+ *
+ * @param dataType the data type.
+ * @param size the number of elements in the buffer.
+ * @param numBanks the number of data banks.
+ * @param offsets the offsets to the first element for all banks.
+ *
+ * @throws ArrayIndexOutOfBoundsException if
+ * <code>numBanks != offsets.length</code>.
+ */
protected DataBuffer(int dataType, int size, int numBanks, int[] offsets) {
this(dataType, size);
if (numBanks != offsets.length)
@@ -99,6 +189,17 @@ public abstract class DataBuffer
offset = offsets[0];
}
+ /**
+ * Returns the size (number of bits) of the specified data type. Valid types
+ * are defined by the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
+ * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
+ * {@link #TYPE_DOUBLE}.
+ *
+ * @param dataType the data type.
+ * @return The number of bits for the specified data type.
+ * @throws IllegalArgumentException if <code>dataType < 0</code> or
+ * <code>dataType > TYPE_DOUBLE</code>.
+ */
public static int getDataTypeSize(int dataType) {
// Maybe this should be a lookup table instead.
switch (dataType)
@@ -118,21 +219,45 @@ public abstract class DataBuffer
}
}
+ /**
+ * Returns the type of the data elements in the data buffer. Valid types
+ * are defined by the constants {@link #TYPE_BYTE}, {@link #TYPE_SHORT},
+ * {@link #TYPE_USHORT}, {@link #TYPE_INT}, {@link #TYPE_FLOAT} and
+ * {@link #TYPE_DOUBLE}.
+ *
+ * @return The type.
+ */
public int getDataType()
{
return dataType;
}
+ /**
+ * Returns the size of the data buffer.
+ *
+ * @return The size.
+ */
public int getSize()
{
return size;
}
+ /**
+ * Returns the element offset for the first data bank.
+ *
+ * @return The element offset.
+ */
public int getOffset()
{
return offset;
}
+ /**
+ * Returns the offsets for all the data banks used by this
+ * <code>DataBuffer</code>.
+ *
+ * @return The offsets.
+ */
public int[] getOffsets()
{
if (offsets == null)
@@ -144,60 +269,166 @@ public abstract class DataBuffer
return offsets;
}
+ /**
+ * Returns the number of data banks for this <code>DataBuffer</code>.
+ * @return The number of data banks.
+ */
public int getNumBanks()
{
return banks;
}
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int i)
{
return getElem(0, i);
}
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
public abstract int getElem(int bank, int i);
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int i, int val)
{
setElem(0, i, val);
}
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
public abstract void setElem(int bank, int i, int val);
+ /**
+ * Returns an element from the first data bank, converted to a
+ * <code>float</code>. The offset (specified in the constructor) is added
+ * to <code>i</code> before accessing the underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
public float getElemFloat(int i)
{
return getElem(i);
}
+ /**
+ * Returns an element from a particular data bank, converted to a
+ * <code>float</code>. The offset (specified in the constructor) is
+ * added to <code>i</code> before accessing the underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
public float getElemFloat(int bank, int i)
{
return getElem(bank, i);
}
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElemFloat(int i, float val)
{
setElem(i, (int) val);
}
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElemFloat(int bank, int i, float val)
{
setElem(bank, i, (int) val);
}
+ /**
+ * Returns an element from the first data bank, converted to a
+ * <code>double</code>. The offset (specified in the constructor) is added
+ * to <code>i</code> before accessing the underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
public double getElemDouble(int i)
{
return getElem(i);
}
+ /**
+ * Returns an element from a particular data bank, converted to a
+ * <code>double</code>. The offset (specified in the constructor) is
+ * added to <code>i</code> before accessing the underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
public double getElemDouble(int bank, int i)
{
return getElem(bank, i);
}
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElemDouble(int i, double val)
{
setElem(i, (int) val);
}
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElemDouble(int bank, int i, double val)
{
setElem(bank, i, (int) val);
diff --git a/libjava/java/awt/image/DataBufferByte.java b/libjava/java/awt/image/DataBufferByte.java
index 84df5510607..c56be6b31dd 100644
--- a/libjava/java/awt/image/DataBufferByte.java
+++ b/libjava/java/awt/image/DataBufferByte.java
@@ -54,12 +54,27 @@ public final class DataBufferByte extends DataBuffer
private byte[] data;
private byte[][] bankData;
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>byte</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
public DataBufferByte(int size)
{
- super(TYPE_BYTE, size);
+ super(TYPE_BYTE, size, 1, 0);
+ bankData = new byte[1][];
data = new byte[size];
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>byte</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
public DataBufferByte(int size, int numBanks)
{
super(TYPE_BYTE, size, numBanks);
@@ -67,18 +82,53 @@ public final class DataBufferByte extends DataBuffer
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ */
public DataBufferByte(byte[] dataArray, int size)
{
- super(TYPE_BYTE, size);
+ super(TYPE_BYTE, size, 1, 0);
+ bankData = new byte[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ */
public DataBufferByte(byte[] dataArray, int size, int offset)
{
super(TYPE_BYTE, size, 1, offset);
+ bankData = new byte[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferByte(byte[][] dataArray, int size)
{
super(TYPE_BYTE, size, dataArray.length);
@@ -86,6 +136,17 @@ public final class DataBufferByte extends DataBuffer
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferByte(byte[][] dataArray, int size, int[] offsets)
{
super(TYPE_BYTE, size, dataArray.length, offsets);
@@ -93,37 +154,87 @@ public final class DataBufferByte extends DataBuffer
data = bankData[0];
}
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
public byte[] getData()
{
return data;
}
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
public byte[] getData(int bank)
{
return bankData[bank];
}
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
public byte[][] getBankData()
{
return bankData;
}
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int i)
{
return data[i+offset] & 0xff; // get unsigned byte as int
}
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int bank, int i)
{
// get unsigned byte as int
return bankData[bank][i+offsets[bank]] & 0xff;
}
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int i, int val)
{
data[i+offset] = (byte) val;
}
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int bank, int i, int val)
{
bankData[bank][i+offsets[bank]] = (byte) val;
diff --git a/libjava/java/awt/image/DataBufferDouble.java b/libjava/java/awt/image/DataBufferDouble.java
index b1291f4165b..305cb00b2ff 100644
--- a/libjava/java/awt/image/DataBufferDouble.java
+++ b/libjava/java/awt/image/DataBufferDouble.java
@@ -58,12 +58,27 @@ public final class DataBufferDouble
private double[] data;
private double[][] bankData;
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>double</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
public DataBufferDouble(int size)
{
- super(TYPE_DOUBLE, size);
+ super(TYPE_DOUBLE, size, 1, 0);
+ bankData = new double[1][];
data = new double[size];
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>double</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
public DataBufferDouble(int size, int numBanks)
{
super(TYPE_DOUBLE, size, numBanks);
@@ -71,18 +86,53 @@ public final class DataBufferDouble
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ */
public DataBufferDouble(double[] dataArray, int size)
{
- super(TYPE_DOUBLE, size);
+ super(TYPE_DOUBLE, size, 1, 0);
+ bankData = new double[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ */
public DataBufferDouble(double[] dataArray, int size, int offset)
{
super(TYPE_DOUBLE, size, 1, offset);
+ bankData = new double[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferDouble(double[][] dataArray, int size)
{
super(TYPE_DOUBLE, size, dataArray.length);
@@ -90,6 +140,17 @@ public final class DataBufferDouble
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferDouble(double[][] dataArray, int size, int[] offsets)
{
super(TYPE_DOUBLE, size, dataArray.length, offsets);
@@ -97,36 +158,86 @@ public final class DataBufferDouble
data = bankData[0];
}
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
public double[] getData()
{
return data;
}
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
public double[] getData(int bank)
{
return bankData[bank];
}
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
public double[][] getBankData()
{
return bankData;
}
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int i)
{
return (int) data[i+offset];
}
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int bank, int i)
{
return (int) bankData[bank][i+offsets[bank]];
}
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int i, int val)
{
data[i+offset] = (double) val;
}
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int bank, int i, int val)
{
bankData[bank][i+offsets[bank]] = (double) val;
diff --git a/libjava/java/awt/image/DataBufferFloat.java b/libjava/java/awt/image/DataBufferFloat.java
index b2d88c16b8b..9673eddb458 100644
--- a/libjava/java/awt/image/DataBufferFloat.java
+++ b/libjava/java/awt/image/DataBufferFloat.java
@@ -56,12 +56,27 @@ public final class DataBufferFloat
private float[] data;
private float[][] bankData;
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>float</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
public DataBufferFloat(int size)
{
- super(TYPE_FLOAT, size);
+ super(TYPE_FLOAT, size, 1, 0);
+ bankData = new float[1][];
data = new float[size];
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>float</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
public DataBufferFloat(int size, int numBanks)
{
super(TYPE_FLOAT, size, numBanks);
@@ -69,18 +84,53 @@ public final class DataBufferFloat
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ */
public DataBufferFloat(float[] dataArray, int size)
{
- super(TYPE_FLOAT, size);
+ super(TYPE_FLOAT, size, 1, 0);
+ bankData = new float[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ */
public DataBufferFloat(float[] dataArray, int size, int offset)
{
super(TYPE_FLOAT, size, 1, offset);
+ bankData = new float[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferFloat(float[][] dataArray, int size)
{
super(TYPE_FLOAT, size, dataArray.length);
@@ -88,6 +138,17 @@ public final class DataBufferFloat
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferFloat(float[][] dataArray, int size, int[] offsets)
{
super(TYPE_FLOAT, size, dataArray.length, offsets);
@@ -95,36 +156,86 @@ public final class DataBufferFloat
data = bankData[0];
}
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
public float[] getData()
{
return data;
}
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
public float[] getData(int bank)
{
return bankData[bank];
}
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
public float[][] getBankData()
{
return bankData;
}
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int i)
{
return (int) data[i+offset];
}
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int bank, int i)
{
return (int) bankData[bank][i+offsets[bank]];
}
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int i, int val)
{
data[i+offset] = (float) val;
}
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int bank, int i, int val)
{
bankData[bank][i+offsets[bank]] = (float) val;
diff --git a/libjava/java/awt/image/DataBufferInt.java b/libjava/java/awt/image/DataBufferInt.java
index 54308fefd02..c5f08530d2b 100644
--- a/libjava/java/awt/image/DataBufferInt.java
+++ b/libjava/java/awt/image/DataBufferInt.java
@@ -54,12 +54,27 @@ public final class DataBufferInt extends DataBuffer
private int[] data;
private int[][] bankData;
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>int</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
public DataBufferInt(int size)
{
- super(TYPE_INT, size);
+ super(TYPE_INT, size, 1, 0);
+ bankData = new int[1][];
data = new int[size];
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>int</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
public DataBufferInt(int size, int numBanks)
{
super(TYPE_INT, size, numBanks);
@@ -67,18 +82,53 @@ public final class DataBufferInt extends DataBuffer
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ */
public DataBufferInt(int[] dataArray, int size)
{
- super(TYPE_INT, size);
+ super(TYPE_INT, size, 1, 0);
+ bankData = new int[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ */
public DataBufferInt(int[] dataArray, int size, int offset)
{
super(TYPE_INT, size, 1, offset);
+ bankData = new int[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferInt(int[][] dataArray, int size)
{
super(TYPE_INT, size, dataArray.length);
@@ -86,6 +136,17 @@ public final class DataBufferInt extends DataBuffer
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferInt(int[][] dataArray, int size, int[] offsets)
{
super(TYPE_INT, size, dataArray.length, offsets);
@@ -93,39 +154,88 @@ public final class DataBufferInt extends DataBuffer
data = bankData[0];
}
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
public int[] getData()
{
return data;
}
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
public int[] getData(int bank)
{
return bankData[bank];
}
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
public int[][] getBankData()
{
return bankData;
}
+ /**
+ * Returns an element from the first data bank. The <code>offset</code> is
+ * added to the specified index before accessing the underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int i)
{
return data[i+offset];
}
+ /**
+ * Returns an element from a particular data bank. The <code>offset</code>
+ * is added to the specified index before accessing the underlying data
+ * array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int bank, int i)
{
// get unsigned int as int
return bankData[bank][i+offsets[bank]];
}
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int i, int val)
{
- data[i+offset] = (int) val;
+ data[i+offset] = val;
}
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int bank, int i, int val)
{
- bankData[bank][i+offsets[bank]] = (int) val;
+ bankData[bank][i+offsets[bank]] = val;
}
}
diff --git a/libjava/java/awt/image/DataBufferShort.java b/libjava/java/awt/image/DataBufferShort.java
index 7a5c3942423..7a095c4e38e 100644
--- a/libjava/java/awt/image/DataBufferShort.java
+++ b/libjava/java/awt/image/DataBufferShort.java
@@ -1,4 +1,5 @@
-/* Copyright (C) 2004 Free Software Foundation
+/* DataBufferShort.java --
+ Copyright (C) 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -54,12 +55,27 @@ public final class DataBufferShort extends DataBuffer
private short[] data;
private short[][] bankData;
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>short</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
public DataBufferShort(int size)
{
- super(TYPE_SHORT, size);
+ super(TYPE_SHORT, size, 1, 0);
+ bankData = new short[1][];
data = new short[size];
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>short</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
public DataBufferShort(int size, int numBanks)
{
super(TYPE_SHORT, size, numBanks);
@@ -67,18 +83,53 @@ public final class DataBufferShort extends DataBuffer
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ */
public DataBufferShort(short[] dataArray, int size)
{
- super(TYPE_SHORT, size);
+ super(TYPE_SHORT, size, 1, 0);
+ bankData = new short[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ * <p>
+ * Note: there is no exception when <code>dataArray</code> is
+ * <code>null</code>, but in that case an exception will be thrown
+ * later if you attempt to access the data buffer.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ */
public DataBufferShort(short[] dataArray, int size, int offset)
{
super(TYPE_SHORT, size, 1, offset);
+ bankData = new short[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferShort(short[][] dataArray, int size)
{
super(TYPE_SHORT, size, dataArray.length);
@@ -86,6 +137,17 @@ public final class DataBufferShort extends DataBuffer
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferShort(short[][] dataArray, int size, int[] offsets)
{
super(TYPE_SHORT, size, dataArray.length, offsets);
@@ -93,36 +155,86 @@ public final class DataBufferShort extends DataBuffer
data = bankData[0];
}
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
public short[] getData()
{
return data;
}
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
public short[] getData(int bank)
{
return bankData[bank];
}
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
public short[][] getBankData()
{
return bankData;
}
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int i)
{
return data[i+offset];
}
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int bank, int i)
{
return bankData[bank][i+offsets[bank]];
}
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int i, int val)
{
data[i+offset] = (short) val;
}
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int bank, int i, int val)
{
bankData[bank][i+offsets[bank]] = (short) val;
diff --git a/libjava/java/awt/image/DataBufferUShort.java b/libjava/java/awt/image/DataBufferUShort.java
index e11b4ab10b2..6efe73d83ab 100644
--- a/libjava/java/awt/image/DataBufferUShort.java
+++ b/libjava/java/awt/image/DataBufferUShort.java
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000, 2002 Free Software Foundation
+/* DataBufferUShort.java --
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -54,12 +55,27 @@ public final class DataBufferUShort extends DataBuffer
private short[] data;
private short[][] bankData;
+ /**
+ * Creates a new data buffer with a single data bank containing the
+ * specified number of <code>short</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ */
public DataBufferUShort(int size)
{
- super(TYPE_USHORT, size);
+ super(TYPE_USHORT, size, 1, 0);
+ bankData = new short[1][];
data = new short[size];
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer with the specified number of data banks,
+ * each containing the specified number of <code>short</code> elements.
+ *
+ * @param size the number of elements in the data bank.
+ * @param numBanks the number of data banks.
+ */
public DataBufferUShort(int size, int numBanks)
{
super(TYPE_USHORT, size, numBanks);
@@ -67,18 +83,53 @@ public final class DataBufferUShort extends DataBuffer
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data bank.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if dataArray is null
+ */
public DataBufferUShort(short[] dataArray, int size)
{
- super(TYPE_USHORT, size);
+ super(TYPE_USHORT, size, 1, 0);
+ if (dataArray == null)
+ throw new NullPointerException();
+ bankData = new short[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data bank, with
+ * the specified offset to the first element.
+ *
+ * @param dataArray the data bank.
+ * @param size the number of elements in the data bank.
+ * @param offset the offset to the first element in the array.
+ *
+ * @throws NullPointerException if dataArray is null
+ */
public DataBufferUShort(short[] dataArray, int size, int offset)
{
super(TYPE_USHORT, size, 1, offset);
+ if (dataArray == null)
+ throw new NullPointerException();
+ bankData = new short[1][];
data = dataArray;
+ bankData[0] = data;
}
+ /**
+ * Creates a new data buffer backed by the specified data banks.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferUShort(short[][] dataArray, int size)
{
super(TYPE_USHORT, size, dataArray.length);
@@ -86,6 +137,17 @@ public final class DataBufferUShort extends DataBuffer
data = bankData[0];
}
+ /**
+ * Creates a new data buffer backed by the specified data banks, with
+ * the specified offsets to the first element in each bank.
+ *
+ * @param dataArray the data banks.
+ * @param size the number of elements in the data bank.
+ * @param offsets the offsets to the first element in each data bank.
+ *
+ * @throws NullPointerException if <code>dataArray</code> is
+ * <code>null</code>.
+ */
public DataBufferUShort(short[][] dataArray, int size, int[] offsets)
{
super(TYPE_USHORT, size, dataArray.length, offsets);
@@ -93,37 +155,87 @@ public final class DataBufferUShort extends DataBuffer
data = bankData[0];
}
+ /**
+ * Returns the first data bank.
+ *
+ * @return The first data bank.
+ */
public short[] getData()
{
return data;
}
+ /**
+ * Returns a data bank.
+ *
+ * @param bank the bank index.
+ * @return A data bank.
+ */
public short[] getData(int bank)
{
return bankData[bank];
}
+ /**
+ * Returns the array underlying this <code>DataBuffer</code>.
+ *
+ * @return The data banks.
+ */
public short[][] getBankData()
{
return bankData;
}
+ /**
+ * Returns an element from the first data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int i)
{
return data[i+offset] & 0xffff; // get unsigned short as int
}
+ /**
+ * Returns an element from a particular data bank. The offset (specified in
+ * the constructor) is added to <code>i</code> before accessing the
+ * underlying data array.
+ *
+ * @param bank the bank index.
+ * @param i the element index.
+ * @return The element.
+ */
public int getElem(int bank, int i)
{
// get unsigned short as int
return bankData[bank][i+offsets[bank]] & 0xffff;
}
+ /**
+ * Sets an element in the first data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int i, int val)
{
data[i+offset] = (short) val;
}
+ /**
+ * Sets an element in a particular data bank. The offset (specified in the
+ * constructor) is added to <code>i</code> before updating the underlying
+ * data array.
+ *
+ * @param bank the data bank index.
+ * @param i the element index.
+ * @param val the new element value.
+ */
public void setElem(int bank, int i, int val)
{
bankData[bank][i+offsets[bank]] = (short) val;
diff --git a/libjava/java/awt/image/DirectColorModel.java b/libjava/java/awt/image/DirectColorModel.java
index 3ac43cf25b6..b1aa6c0d335 100644
--- a/libjava/java/awt/image/DirectColorModel.java
+++ b/libjava/java/awt/image/DirectColorModel.java
@@ -1,4 +1,5 @@
-/* Copyright (C) 1999, 2000, 2002 Free Software Foundation
+/* DirectColorModel.java --
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -37,13 +38,14 @@ exception statement from your version. */
package java.awt.image;
+import gnu.java.awt.Buffers;
+
import java.awt.Point;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
-import gnu.java.awt.Buffers;
/**
- * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
+ * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
* @author C. Brian Jones (cbj@gnu.org)
* @author Mark Benvenuto (mcb54@columbia.edu)
*/
@@ -56,7 +58,7 @@ public class DirectColorModel extends PackedColorModel
* most likely order of alpha, red, green, blue from the most significant
* byte to the least significant byte.
*
- * @param bits the number of bits wide used for bit size of pixel values
+ * @param pixelBits the number of bits wide used for bit size of pixel values
* @param rmask the bits describing the red component of a pixel
* @param gmask the bits describing the green component of a pixel
* @param bmask the bits describing the blue component of a pixel
@@ -77,7 +79,7 @@ public class DirectColorModel extends PackedColorModel
* most likely order of red, green, blue from the most significant
* byte to the least significant byte.
*
- * @param bits the number of bits wide used for bit size of pixel values
+ * @param pixelBits the number of bits wide used for bit size of pixel values
* @param rmask the bits describing the red component of a pixel
* @param gmask the bits describing the green component of a pixel
* @param bmask the bits describing the blue component of a pixel
@@ -162,7 +164,7 @@ public class DirectColorModel extends PackedColorModel
return extractAndScaleSample(pixel, 3);
}
- private final int extractAndNormalizeSample(int pixel, int component)
+ private int extractAndNormalizeSample(int pixel, int component)
{
int value = extractAndScaleSample(pixel, component);
if (hasAlpha() && isAlphaPremultiplied())
@@ -170,7 +172,7 @@ public class DirectColorModel extends PackedColorModel
return value;
}
- private final int extractAndScaleSample(int pixel, int component)
+ private int extractAndScaleSample(int pixel, int component)
{
int field = pixel & getMask(component);
int to8BitShift =
@@ -303,7 +305,7 @@ public class DirectColorModel extends PackedColorModel
* @param highBit the position of the most significant bit in the
* val parameter.
*/
- private final int valueToField(int val, int component, int highBit)
+ private int valueToField(int val, int component, int highBit)
{
int toFieldShift =
getComponentSize(component) + shifts[component] - highBit;
@@ -317,7 +319,7 @@ public class DirectColorModel extends PackedColorModel
* Converts a 16 bit value to the correct field bits based on the
* information derived from the field masks.
*/
- private final int value16ToField(int val, int component)
+ private int value16ToField(int val, int component)
{
int toFieldShift = getComponentSize(component) + shifts[component] - 16;
return (toFieldShift>0) ?
diff --git a/libjava/java/awt/image/IndexColorModel.java b/libjava/java/awt/image/IndexColorModel.java
index 9ceb0bf0944..6791589032e 100644
--- a/libjava/java/awt/image/IndexColorModel.java
+++ b/libjava/java/awt/image/IndexColorModel.java
@@ -38,7 +38,29 @@ exception statement from your version. */
package java.awt.image;
+import java.awt.color.ColorSpace;
+import java.math.BigInteger;
+
/**
+ * Color model similar to pseudo visual in X11.
+ *
+ * This color model maps linear pixel values to actual RGB and alpha colors.
+ * Thus, pixel values are indexes into the color map. Each color component is
+ * an 8-bit unsigned value.
+ *
+ * The IndexColorModel supports a map of valid pixels, allowing the
+ * representation of holes in the the color map. The valid map is represented
+ * as a BigInteger where each bit indicates the validity of the map entry with
+ * the same index.
+ *
+ * Colors can have alpha components for transparency support. If alpha
+ * component values aren't given, color values are opaque. The model also
+ * supports a reserved pixel value to represent completely transparent colors,
+ * no matter what the actual color component values are.
+ *
+ * IndexColorModel supports anywhere from 1 to 16 bit index values. The
+ * allowed transfer types are DataBuffer.TYPE_BYTE and DataBuffer.TYPE_USHORT.
+ *
* @author C. Brian Jones (cbj@gnu.org)
*/
public class IndexColorModel extends ColorModel
@@ -47,6 +69,7 @@ public class IndexColorModel extends ColorModel
private boolean opaque;
private int trans = -1;
private int[] rgb;
+ private BigInteger validBits = BigInteger.ZERO;
/**
* Each array much contain <code>size</code> elements. For each
@@ -127,6 +150,9 @@ public class IndexColorModel extends ColorModel
| (blues[i] & 0xff));
}
}
+
+ // Generate a bigint with 1's for every pixel
+ validBits = validBits.setBit(size).subtract(BigInteger.ONE);
}
/**
@@ -140,6 +166,7 @@ public class IndexColorModel extends ColorModel
* @param cmap packed color components
* @param start the offset of the first color component in <code>cmap</code>
* @param hasAlpha <code>cmap</code> has alpha values
+ * @throws IllegalArgumentException if bits < 1, bits > 16, or size < 1.
*/
public IndexColorModel (int bits, int size, byte[] cmap, int start,
boolean hasAlpha)
@@ -148,25 +175,155 @@ public class IndexColorModel extends ColorModel
}
/**
- * Each array much contain <code>size</code> elements. For each
- * array, the i-th color is described by reds[i], greens[i],
- * blues[i], alphas[i], unless alphas is not specified, then all the
- * colors are opaque except for the transparent color.
- *
+ * Construct an IndexColorModel from an array of red, green, blue, and
+ * optional alpha components. The component values are interleaved as RGB(A).
+ *
* @param bits the number of bits needed to represent <code>size</code> colors
* @param size the number of colors in the color map
- * @param cmap packed color components
+ * @param cmap interleaved color components
* @param start the offset of the first color component in <code>cmap</code>
* @param hasAlpha <code>cmap</code> has alpha values
* @param trans the index of the transparent color
+ * @throws IllegalArgumentException if bits < 1, bits > 16, or size < 1.
*/
public IndexColorModel (int bits, int size, byte[] cmap, int start,
boolean hasAlpha, int trans)
{
super (bits);
+ if (bits > 16)
+ throw new IllegalArgumentException("bits > 16");
+ if (size < 1)
+ throw new IllegalArgumentException("size < 1");
+ map_size = size;
+ opaque = !hasAlpha;
+ this.trans = trans;
+
+ rgb = new int[size];
+ if (hasAlpha)
+ {
+ for (int i = 0; i < size; i++)
+ rgb[i] =
+ // alpha
+ ((cmap[4 * i + 3 + start] & 0xff) << 24
+ // red
+ | ((cmap[4 * i + start] & 0xff) << 16)
+ // green
+ | ((cmap[4 * i + 1 + start] & 0xff) << 8)
+ // blue
+ | (cmap[4 * i + 2 + start] & 0xff));
+ }
+ else
+ {
+ for (int i = 0; i < size; i++)
+ rgb[i] = (0xff000000
+ // red
+ | ((cmap[3 * i + start] & 0xff) << 16)
+ // green
+ | ((cmap[3 * i + 1 + start] & 0xff) << 8)
+ // blue
+ | (cmap[3 * i + 2 + start] & 0xff));
+ }
+
+ // Generate a bigint with 1's for every pixel
+ validBits = validBits.setBit(size).subtract(BigInteger.ONE);
+ }
+
+ /**
+ * Construct an IndexColorModel from an array of <code>size</code> packed
+ * colors. Each int element contains 8-bit red, green, blue, and optional
+ * alpha values packed in order. If hasAlpha is false, then all the colors
+ * are opaque except for the transparent color.
+ *
+ * @param bits the number of bits needed to represent <code>size</code> colors
+ * @param size the number of colors in the color map
+ * @param cmap packed color components
+ * @param start the offset of the first color component in <code>cmap</code>
+ * @param hasAlpha <code>cmap</code> has alpha values
+ * @param trans the index of the transparent color
+ * @param transferType DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT
+ * @throws IllegalArgumentException if bits < 1, bits > 16, or size < 1.
+ * @throws IllegalArgumentException if transferType is something other than
+ * TYPE_BYTE or TYPE_USHORT.
+ */
+ public IndexColorModel (int bits, int size, int[] cmap, int start,
+ boolean hasAlpha, int trans, int transferType)
+ {
+ super(bits * 4, // total bits, sRGB, four channels
+ nArray(bits, 4), // bits for each channel
+ ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
+ true, // has alpha
+ false, // not premultiplied
+ TRANSLUCENT, transferType);
+ if (transferType != DataBuffer.TYPE_BYTE
+ && transferType != DataBuffer.TYPE_USHORT)
+ throw new IllegalArgumentException();
+ if (bits > 16)
+ throw new IllegalArgumentException("bits > 16");
+ if (size < 1)
+ throw new IllegalArgumentException("size < 1");
map_size = size;
opaque = !hasAlpha;
this.trans = trans;
+
+ rgb = new int[size];
+ if (!hasAlpha)
+ for (int i = 0; i < size; i++)
+ rgb[i] = cmap[i + start] | 0xff000000;
+ else
+ System.arraycopy(cmap, start, rgb, 0, size);
+
+ // Generate a bigint with 1's for every pixel
+ validBits = validBits.setBit(size).subtract(BigInteger.ONE);
+ }
+
+ /**
+ * Construct an IndexColorModel using a colormap with holes.
+ *
+ * The IndexColorModel is built from the array of ints defining the
+ * colormap. Each element contains red, green, blue, and alpha
+ * components. The ColorSpace is sRGB. The transparency value is
+ * automatically determined.
+ *
+ * This constructor permits indicating which colormap entries are valid,
+ * using the validBits argument. Each entry in cmap is valid if the
+ * corresponding bit in validBits is set.
+ *
+ * @param bits the number of bits needed to represent <code>size</code> colors
+ * @param size the number of colors in the color map
+ * @param cmap packed color components
+ * @param start the offset of the first color component in <code>cmap</code>
+ * @param transferType DataBuffer.TYPE_BYTE or DataBuffer.TYPE_USHORT
+ * @throws IllegalArgumentException if bits < 1, bits > 16, or size < 1.
+ * @throws IllegalArgumentException if transferType is something other than
+ * TYPE_BYTE or TYPE_USHORT.
+ */
+ public IndexColorModel (int bits, int size, int[] cmap, int start,
+ int transferType, BigInteger validBits)
+ {
+ super(bits * 4, // total bits, sRGB, four channels
+ nArray(bits, 4), // bits for each channel
+ ColorSpace.getInstance(ColorSpace.CS_sRGB), // sRGB
+ true, // has alpha
+ false, // not premultiplied
+ TRANSLUCENT, transferType);
+ if (transferType != DataBuffer.TYPE_BYTE
+ && transferType != DataBuffer.TYPE_USHORT)
+ throw new IllegalArgumentException();
+ if (bits > 16)
+ throw new IllegalArgumentException("bits > 16");
+ if (size < 1)
+ throw new IllegalArgumentException("size < 1");
+ map_size = size;
+ opaque = false;
+ this.trans = -1;
+ this.validBits = validBits;
+
+ rgb = new int[size];
+ if (!hasAlpha)
+ for (int i = 0; i < size; i++)
+ rgb[i] = cmap[i + start] | 0xff000000;
+ else
+ System.arraycopy(cmap, start, rgb, 0, size);
}
public final int getMapSize ()
@@ -279,11 +436,79 @@ public class IndexColorModel extends ColorModel
return 0;
}
- //pixel_bits is number of bits to be in generated mask
+ /**
+ * Get the RGB color values of all pixels in the map using the default
+ * RGB color model.
+ *
+ * @param rgb The destination array.
+ */
+ public final void getRGBs (int[] rgb)
+ {
+ System.arraycopy(this.rgb, 0, rgb, 0, map_size);
+ }
+
+ //pixel_bits is number of bits to be in generated mask
private int generateMask (int offset)
{
return (((2 << pixel_bits ) - 1) << (pixel_bits * offset));
}
+ /** Return true if pixel is valid, false otherwise. */
+ public boolean isValid(int pixel)
+ {
+ return validBits.testBit(pixel);
+ }
+
+ /** Return true if all pixels are valid, false otherwise. */
+ public boolean isValid()
+ {
+ // Generate a bigint with 1's for every pixel
+ BigInteger allbits = new BigInteger("0");
+ allbits.setBit(map_size);
+ allbits.subtract(new BigInteger("1"));
+ return allbits.equals(validBits);
+ }
+
+ /**
+ * Returns a BigInteger where each bit represents an entry in the color
+ * model. If the bit is on, the entry is valid.
+ */
+ public BigInteger getValidPixels()
+ {
+ return validBits;
+ }
+
+ /**
+ * Construct a BufferedImage with rgb pixel values from a Raster.
+ *
+ * Constructs a new BufferedImage in which each pixel is an RGBA int from
+ * a Raster with index-valued pixels. If this model has no alpha component
+ * or transparent pixel, the type of the new BufferedImage is TYPE_INT_RGB.
+ * Otherwise the type is TYPE_INT_ARGB. If forceARGB is true, the type is
+ * forced to be TYPE_INT_ARGB no matter what.
+ *
+ * @param raster The source of pixel values.
+ * @param forceARGB True if type must be TYPE_INT_ARGB.
+ * @return New BufferedImage with RBGA int pixel values.
+ */
+ public BufferedImage convertToIntDiscrete(Raster raster, boolean forceARGB)
+ {
+ int type = forceARGB ? BufferedImage.TYPE_INT_ARGB
+ : ((opaque && trans == -1) ? BufferedImage.TYPE_INT_RGB :
+ BufferedImage.TYPE_INT_ARGB);
+
+ // FIXME: assuming that raster has only 1 band since pixels are supposed
+ // to be int indexes.
+ // FIXME: it would likely be more efficient to fetch a complete array,
+ // but it would take much more memory.
+ // FIXME: I'm not sure if transparent pixels or alpha values need special
+ // handling here.
+ BufferedImage im = new BufferedImage(raster.width, raster.height, type);
+ for (int x = raster.minX; x < raster.width + raster.minX; x++)
+ for (int y = raster.minY; y < raster.height + raster.minY; y++)
+ im.setRGB(x, y, rgb[raster.getSample(x, y, 0)]);
+
+ return im;
+ }
}
diff --git a/libjava/java/awt/image/LookupOp.java b/libjava/java/awt/image/LookupOp.java
new file mode 100644
index 00000000000..523aba45144
--- /dev/null
+++ b/libjava/java/awt/image/LookupOp.java
@@ -0,0 +1,252 @@
+/* LookupOp.java -- Filter that converts each pixel using a lookup table.
+ Copyright (C) 2004 Free Software Foundation
+
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.awt.image;
+
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * LookupOp is a filter that converts each pixel using a lookup table.
+ *
+ * For filtering Rasters, the lookup table must have either one component
+ * that is applied to all bands, or one component for every band in the
+ * Rasters.
+ *
+ * For BufferedImages, the lookup table may apply to both color and alpha
+ * components. If the lookup table contains one component, or if there are
+ * the same number of components as color components in the source, the table
+ * applies to all color components. Otherwise the table applies to all
+ * components including alpha. Alpha premultiplication is ignored during the
+ * lookup filtering.
+ *
+ * After filtering, if color conversion is necessary, the conversion happens,
+ * taking alpha premultiplication into account.
+ *
+ * @author jlquinn
+ */
+public class LookupOp implements BufferedImageOp, RasterOp
+{
+ private LookupTable lut;
+ private RenderingHints hints;
+
+ /** Construct a new LookupOp.
+ *
+ * @param lookup LookupTable to use.
+ * @param hints Rendering hints (can be null).
+ */
+ public LookupOp(LookupTable lookup, RenderingHints hints)
+ {
+ lut = lookup;
+ this.hints = hints;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage, java.awt.image.BufferedImage)
+ */
+ public BufferedImage filter(BufferedImage src, BufferedImage dst)
+ {
+ if (src.getColorModel() instanceof IndexColorModel)
+ throw new IllegalArgumentException("LookupOp.filter: IndexColorModel "
+ + "not allowed");
+ if (dst == null)
+ dst = createCompatibleDestImage(src, src.getColorModel());
+
+ // Set up for potential colormodel mismatch
+ BufferedImage tgt;
+ if (dst.getColorModel().equals(src.getColorModel()))
+ tgt = dst;
+ else
+ tgt = createCompatibleDestImage(src, src.getColorModel());
+
+ Raster sr = src.getRaster();
+ WritableRaster dr = tgt.getRaster();
+
+ if (src.getColorModel().hasAlpha() &&
+ (lut.getNumComponents() == 1 ||
+ lut.getNumComponents() == src.getColorModel().getNumColorComponents()))
+ {
+ // Need to ignore alpha for lookup
+ int[] dbuf = new int[src.getColorModel().getNumComponents()];
+ int tmpBands = src.getColorModel().getNumColorComponents();
+ int[] tmp = new int[tmpBands];
+
+ // Filter the pixels
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ {
+ // Filter only color components, but also copy alpha
+ sr.getPixel(x, y, dbuf);
+ System.arraycopy(dbuf, 0, tmp, 0, tmpBands);
+ dr.setPixel(x, y, lut.lookupPixel(tmp, dbuf));
+ }
+ }
+ else if (lut.getNumComponents() != 1
+ &&
+ lut.getNumComponents() != src.getColorModel().getNumComponents())
+ throw new IllegalArgumentException("LookupOp.filter: "
+ + "Incompatible lookup "
+ + "table and source image");
+
+ // No alpha to ignore
+ int[] dbuf = new int[src.getColorModel().getNumComponents()];
+
+ // Filter the pixels
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ dr.setPixel(x, y, lut.lookupPixel(sr.getPixel(x, y, dbuf), dbuf));
+
+ if (tgt != dst)
+ {
+ // Convert between color models.
+ // TODO Check that premultiplied alpha is handled correctly here.
+ Graphics2D gg = dst.createGraphics();
+ gg.setRenderingHints(hints);
+ gg.drawImage(tgt, 0, 0, null);
+ gg.dispose();
+ }
+
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
+ */
+ public Rectangle2D getBounds2D(BufferedImage src)
+ {
+ return src.getRaster().getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage, java.awt.image.ColorModel)
+ */
+ public BufferedImage createCompatibleDestImage(BufferedImage src,
+ ColorModel dstCM)
+ {
+ // FIXME: set properties to those in src
+ return new BufferedImage(dstCM,
+ src.getRaster().createCompatibleWritableRaster(),
+ src.isPremultiplied, null);
+ }
+
+ /** Return corresponding destination point for source point.
+ *
+ * LookupOp will return the value of src unchanged.
+ * @param src The source point.
+ * @param dst The destination point.
+ * @see java.awt.image.RasterOp#getPoint2D(java.awt.geom.Point2D, java.awt.geom.Point2D)
+ */
+ public Point2D getPoint2D(Point2D src, Point2D dst)
+ {
+ if (dst == null)
+ return (Point2D) src.clone();
+
+ dst.setLocation(src);
+ return dst;
+ }
+
+ /** Return the LookupTable for this op. */
+ public LookupTable getTable()
+ {
+ return lut;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getRenderingHints()
+ */
+ public RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ /** Filter a raster through a lookup table.
+ *
+ * Applies the lookup table for this Rasterop to each pixel of src and
+ * puts the results in dest. If dest is null, a new Raster is created and
+ * returned.
+ *
+ * @param src The source raster.
+ * @param dest The destination raster.
+ * @return The WritableRaster with the filtered pixels.
+ * @throws IllegalArgumentException if lookup table has more than one
+ * component but not the same as src and dest.
+ * @see java.awt.image.RasterOp#filter(java.awt.image.Raster, java.awt.image.WritableRaster)
+ */
+ public WritableRaster filter(Raster src, WritableRaster dest)
+ {
+ if (dest == null)
+ // Allocate a raster if needed
+ dest = createCompatibleDestRaster(src);
+ else
+ if (src.getNumBands() != dest.getNumBands())
+ throw new IllegalArgumentException();
+
+ if (lut.getNumComponents() != 1
+ && lut.getNumComponents() != src.getNumBands())
+ throw new IllegalArgumentException();
+
+
+ // Allocate pixel storage.
+ int[] tmp = new int[src.getNumBands()];
+
+ // Filter the pixels
+ for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
+ for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
+ dest.setPixel(x, y, lut.lookupPixel(src.getPixel(x, y, tmp), tmp));
+ return dest;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
+ */
+ public Rectangle2D getBounds2D(Raster src)
+ {
+ return src.getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
+ */
+ public WritableRaster createCompatibleDestRaster(Raster src)
+ {
+ return src.createCompatibleWritableRaster();
+ }
+
+}
diff --git a/libjava/java/awt/image/MemoryImageSource.java b/libjava/java/awt/image/MemoryImageSource.java
index ddd5800f14f..07e42cf077d 100644
--- a/libjava/java/awt/image/MemoryImageSource.java
+++ b/libjava/java/awt/image/MemoryImageSource.java
@@ -1,5 +1,5 @@
/* MemoryImageSource.java -- Java class for providing image data
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,8 +38,6 @@ exception statement from your version. */
package java.awt.image;
-import java.awt.Image;
-import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
@@ -54,8 +52,16 @@ public class MemoryImageSource implements ImageProducer
private Vector consumers = new Vector();
/**
- Constructs an ImageProducer from memory
- */
+ * Construct an image producer that reads image data from a byte
+ * array.
+ *
+ * @param w width of image
+ * @param h height of image
+ * @param cm the color model used to represent pixel values
+ * @param pix a byte array of pixel values
+ * @param off the offset into the array at which the first pixel is stored
+ * @param scan the number of array elements that represents a single pixel row
+ */
public MemoryImageSource(int w, int h, ColorModel cm,
byte pix[], int off, int scan)
{
@@ -75,12 +81,19 @@ public class MemoryImageSource implements ImageProducer
scansize = scan;
this.props = props;
int max = (( scansize > width ) ? scansize : width );
- pixelb = new byte[ max * height ];
- System.arraycopy( pix, 0, pixelb, 0, max * height );
+ pixelb = pix;
}
/**
- Constructs an ImageProducer from memory
- */
+ * Construct an image producer that reads image data from an
+ * integer array.
+ *
+ * @param w width of image
+ * @param h height of image
+ * @param cm the color model used to represent pixel values
+ * @param pix an integer array of pixel values
+ * @param off the offset into the array at which the first pixel is stored
+ * @param scan the number of array elements that represents a single pixel row
+ */
public MemoryImageSource(int w, int h, ColorModel cm,
int pix[], int off, int scan)
{
@@ -101,8 +114,7 @@ public class MemoryImageSource implements ImageProducer
scansize = scan;
this.props = props;
int max = (( scansize > width ) ? scansize : width );
- pixeli = new int[ max * height ];
- System.arraycopy( pix, 0, pixeli, 0, max * height );
+ pixeli = pix;
}
/**
Constructs an ImageProducer from memory using the default RGB ColorModel
@@ -166,9 +178,12 @@ public class MemoryImageSource implements ImageProducer
Vector list = (Vector) consumers.clone();
for(int i = 0; i < list.size(); i++) {
ic = (ImageConsumer) list.elementAt(i);
- sendPicture( ic );
- ic.imageComplete( ImageConsumer.STATICIMAGEDONE );
- }
+ sendPicture( ic );
+ if (animated)
+ ic.imageComplete( ImageConsumer.SINGLEFRAME );
+ else
+ ic.imageComplete( ImageConsumer.STATICIMAGEDONE );
+ }
}
/**
@@ -261,13 +276,14 @@ public class MemoryImageSource implements ImageProducer
}
if( pixeli != null ) {
int[] pixelbuf = new int[w * h];
- for (int row = y; row < h; row++)
- System.arraycopy(pixeli, row * scansize + x + offset, pixelbuf, row * w, w);
+ for (int row = y; row < y + h; row++)
+ System.arraycopy(pixeli, row * scansize + x + offset, pixelbuf, 0, w * h);
ic.setPixels( x, y, w, h, cm, pixelbuf, 0, w );
} else {
byte[] pixelbuf = new byte[w * h];
- for (int row = y; row < h; row++)
- System.arraycopy(pixelb, row * scansize + x + offset, pixelbuf, row * w, w);
+ for (int row = y; row < y + h; row++)
+ System.arraycopy(pixelb, row * scansize + x + offset, pixelbuf, 0, w * h);
+
ic.setPixels( x, y, w, h, cm, pixelbuf, 0, w );
}
ic.imageComplete( ImageConsumer.SINGLEFRAME );
@@ -306,13 +322,13 @@ public class MemoryImageSource implements ImageProducer
}
if( pixeli != null ) {
int[] pixelbuf = new int[w * h];
- for (int row = y; row < h; row++)
- System.arraycopy(pixeli, row * scansize + x + offset, pixelbuf, row * w, w);
+ for (int row = y; row < y + h; row++)
+ System.arraycopy(pixeli, row * scansize + x + offset, pixelbuf, 0, w * h);
ic.setPixels( x, y, w, h, cm, pixelbuf, 0, w );
} else {
byte[] pixelbuf = new byte[w * h];
- for (int row = y; row < h; row++)
- System.arraycopy(pixelb, row * scansize + x + offset, pixelbuf, row * w, w);
+ for (int row = y; row < y + h; row++)
+ System.arraycopy(pixelb, row * scansize + x + offset, pixelbuf, 0, w * h);
ic.setPixels( x, y, w, h, cm, pixelbuf, 0, w );
}
if( framenotify == true )
diff --git a/libjava/java/awt/image/MultiPixelPackedSampleModel.java b/libjava/java/awt/image/MultiPixelPackedSampleModel.java
new file mode 100644
index 00000000000..0525d37bd42
--- /dev/null
+++ b/libjava/java/awt/image/MultiPixelPackedSampleModel.java
@@ -0,0 +1,387 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.awt.image;
+
+import gnu.java.awt.Buffers;
+
+/**
+ * MultiPixelPackedSampleModel provides a single band model that supports
+ * multiple pixels in a single unit. Pixels have 2^n bits and 2^k pixels fit
+ * per data element.
+ *
+ * @author Jerry Quinn <jlquinn@optonline.net>
+ */
+public class MultiPixelPackedSampleModel extends SampleModel
+{
+ private int scanlineStride;
+ private int[] bitMasks;
+ private int[] bitOffsets;
+ private int[] sampleSize;
+ private int dataBitOffset;
+ private int elemBits;
+ private int numberOfBits;
+ private int numElems;
+
+ public MultiPixelPackedSampleModel(int dataType, int w, int h,
+ int numberOfBits)
+ {
+ this(dataType, w, h, 0, numberOfBits, 0);
+ }
+
+ public MultiPixelPackedSampleModel(int dataType, int w, int h,
+ int numberOfBits, int scanlineStride,
+ int dataBitOffset)
+ {
+ super(dataType, w, h, 1);
+
+ switch (dataType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ elemBits = 8;
+ break;
+ case DataBuffer.TYPE_USHORT:
+ elemBits = 16;
+ break;
+ case DataBuffer.TYPE_INT:
+ elemBits = 32;
+ break;
+ default:
+ throw new IllegalArgumentException("MultiPixelPackedSampleModel"
+ + " unsupported dataType");
+ }
+
+ this.dataBitOffset = dataBitOffset;
+
+ this.numberOfBits = numberOfBits;
+ if (numberOfBits > elemBits)
+ throw new RasterFormatException("MultiPixelPackedSampleModel pixel size"
+ + " larger than dataType");
+ switch (numberOfBits)
+ {
+ case 1: case 2: case 4: case 8: case 16: case 32: break;
+ default:
+ throw new RasterFormatException("MultiPixelPackedSampleModel pixel"
+ + " size not 2^n bits");
+ }
+ numElems = elemBits / numberOfBits;
+
+ // Compute scan line large enough for w pixels.
+ if (scanlineStride == 0)
+ scanlineStride = ((dataBitOffset + w * numberOfBits) / elemBits) + 1;
+ this.scanlineStride = scanlineStride;
+
+
+ sampleSize = new int[1];
+ sampleSize[0] = numberOfBits;
+
+ bitMasks = new int[numElems];
+ bitOffsets = new int[numElems];
+ for (int i=0; i < numElems; i++)
+ {
+ bitOffsets[i] = numberOfBits * i;
+ bitMasks[i] = ((1 << numberOfBits) - 1) << bitOffsets[i];
+ }
+ }
+
+ public SampleModel createCompatibleSampleModel(int w, int h)
+ {
+ /* FIXME: We can avoid recalculation of bit offsets and sample
+ sizes here by passing these from the current instance to a
+ special private constructor. */
+ return new MultiPixelPackedSampleModel(dataType, w, h, numberOfBits);
+ }
+
+
+ /**
+ * Creates a DataBuffer for holding pixel data in the format and
+ * layout described by this SampleModel. The returned buffer will
+ * consist of one single bank.
+ */
+ public DataBuffer createDataBuffer()
+ {
+ int size;
+
+ // FIXME: The comment refers to SinglePixelPackedSampleModel. See if the
+ // same can be done for MultiPixelPackedSampleModel.
+ // We can save (scanlineStride - width) pixels at the very end of
+ // the buffer. The Sun reference implementation (J2SE 1.3.1 and
+ // 1.4.1_01) seems to do this; tested with Mauve test code.
+ size = scanlineStride * height;
+
+ return Buffers.createBuffer(getDataType(), size);
+ }
+
+
+ public int getNumDataElements()
+ {
+ return 1;
+ }
+
+ public int[] getSampleSize()
+ {
+ return sampleSize;
+ }
+
+ public int getSampleSize(int band)
+ {
+ return sampleSize[0];
+ }
+
+ public int getOffset(int x, int y)
+ {
+ return scanlineStride * y + ((dataBitOffset + x*numberOfBits) / elemBits);
+ }
+
+ public int getBitOffset(int x)
+ {
+ return (dataBitOffset + x*numberOfBits) % elemBits;
+ }
+
+ public int getDataBitOffset()
+ {
+ return dataBitOffset;
+ }
+
+ public int getScanlineStride()
+ {
+ return scanlineStride;
+ }
+
+ public int getPixelBitStride()
+ {
+ return numberOfBits;
+ }
+
+
+ public SampleModel createSubsetSampleModel(int[] bands)
+ {
+ int numBands = bands.length;
+ if (numBands != 1)
+ throw new RasterFormatException("MultiPixelPackedSampleModel only"
+ + " supports one band");
+
+ return new MultiPixelPackedSampleModel(dataType, width, height,
+ numberOfBits, scanlineStride,
+ dataBitOffset);
+ }
+
+ /**
+ * Extract one pixel and return in an array of transfer type.
+ *
+ * Extracts the pixel at x, y from data and stores into the 0th index of the
+ * array obj, since there is only one band. If obj is null, a new array of
+ * getTransferType() is created.
+ *
+ * @param x The x-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param y The y-coordinate of the pixel rectangle to store in <code>obj</code>.
+ * @param obj The primitive array to store the pixels into or null to force creation.
+ * @param data The DataBuffer that is the source of the pixel data.
+ * @return The primitive array containing the pixel data.
+ * @see java.awt.image.SampleModel#getDataElements(int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public Object getDataElements(int x, int y, Object obj,
+ DataBuffer data)
+ {
+ int pixel = getSample(x, y, 0, data);
+ switch (getTransferType())
+ {
+ case DataBuffer.TYPE_BYTE:
+ if (obj == null) obj = new byte[1];
+ ((byte[])obj)[0] = (byte)pixel;
+ return obj;
+ case DataBuffer.TYPE_USHORT:
+ if (obj == null) obj = new short[1];
+ ((short[])obj)[0] = (short)pixel;
+ return obj;
+ case DataBuffer.TYPE_INT:
+ if (obj == null) obj = new int[1];
+ ((int[])obj)[0] = pixel;
+ return obj;
+ default:
+ // Seems like the only sensible thing to do.
+ throw new ClassCastException();
+ }
+ }
+
+ public int[] getPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ if (iArray == null) iArray = new int[1];
+ iArray[0] = getSample(x, y, 0, data);
+
+ return iArray;
+ }
+
+ public int[] getPixels(int x, int y, int w, int h, int[] iArray,
+ DataBuffer data)
+ {
+ int offset = getOffset(x, y);
+ if (iArray == null) iArray = new int[w*h];
+ int outOffset = 0;
+ for (y=0; y<h; y++)
+ {
+ int lineOffset = offset;
+ for (x=0; x<w;)
+ {
+ int samples = data.getElem(lineOffset++);
+ for (int b=0; b<numElems && x<w; b++)
+ {
+ iArray[outOffset++] = (samples & bitMasks[b]) >>> bitOffsets[b];
+ x++;
+ }
+ }
+ offset += scanlineStride;
+ }
+ return iArray;
+ }
+
+ public int getSample(int x, int y, int b, DataBuffer data)
+ {
+ int pos =
+ ((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
+ int offset = getOffset(x, y);
+ int samples = data.getElem(offset);
+ return (samples & bitMasks[pos]) >>> bitOffsets[pos];
+ }
+
+ /**
+ * Set the pixel at x, y to the value in the first element of the primitive
+ * array obj.
+ *
+ * @param x The x-coordinate of the data elements in <code>obj</code>.
+ * @param y The y-coordinate of the data elements in <code>obj</code>.
+ * @param obj The primitive array containing the data elements to set.
+ * @param data The DataBuffer to store the data elements into.
+ * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, java.lang.Object, java.awt.image.DataBuffer)
+ */
+ public void setDataElements(int x, int y, Object obj, DataBuffer data)
+ {
+ int transferType = getTransferType();
+ if (getTransferType() != data.getDataType())
+ {
+ throw new IllegalArgumentException("transfer type ("+
+ getTransferType()+"), "+
+ "does not match data "+
+ "buffer type (" +
+ data.getDataType() +
+ ").");
+ }
+
+ int offset = getOffset(x, y);
+
+ try
+ {
+ switch (transferType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ {
+ DataBufferByte out = (DataBufferByte) data;
+ byte[] in = (byte[]) obj;
+ out.getData()[offset] = in[0];
+ return;
+ }
+ case DataBuffer.TYPE_USHORT:
+ {
+ DataBufferUShort out = (DataBufferUShort) data;
+ short[] in = (short[]) obj;
+ out.getData()[offset] = in[0];
+ return;
+ }
+ case DataBuffer.TYPE_INT:
+ {
+ DataBufferInt out = (DataBufferInt) data;
+ int[] in = (int[]) obj;
+ out.getData()[offset] = in[0];
+ return;
+ }
+ default:
+ throw new ClassCastException("Unsupported data type");
+ }
+ }
+ catch (ArrayIndexOutOfBoundsException aioobe)
+ {
+ String msg = "While writing data elements" +
+ ", x="+x+", y="+y+
+ ", width="+width+", height="+height+
+ ", scanlineStride="+scanlineStride+
+ ", offset="+offset+
+ ", data.getSize()="+data.getSize()+
+ ", data.getOffset()="+data.getOffset()+
+ ": " +
+ aioobe;
+ throw new ArrayIndexOutOfBoundsException(msg);
+ }
+ }
+
+ public void setPixel(int x, int y, int[] iArray, DataBuffer data)
+ {
+ setSample(x, y, 0, iArray[0], data);
+ }
+
+ public void setSample(int x, int y, int b, int s, DataBuffer data)
+ {
+ int bitpos =
+ ((dataBitOffset + x * numberOfBits) % elemBits) / numberOfBits;
+ int offset = getOffset(x, y);
+
+ s = s << bitOffsets[bitpos];
+ s = s & bitMasks[bitpos];
+
+ int sample = data.getElem(offset);
+ sample |= s;
+ data.setElem(offset, sample);
+ }
+
+ /**
+ * Creates a String with some information about this SampleModel.
+ * @return A String describing this SampleModel.
+ * @see java.lang.Object#toString()
+ */
+ public String toString()
+ {
+ StringBuffer result = new StringBuffer();
+ result.append(getClass().getName());
+ result.append("[");
+ result.append("scanlineStride=").append(scanlineStride);
+ for(int i=0; i < bitMasks.length; i+=1)
+ {
+ result.append(", mask[").append(i).append("]=0x").append(Integer.toHexString(bitMasks[i]));
+ }
+
+ result.append("]");
+ return result.toString();
+ }
+}
diff --git a/libjava/java/awt/image/PackedColorModel.java b/libjava/java/awt/image/PackedColorModel.java
index 2d8b0e1ab3d..1f18cf68eb1 100644
--- a/libjava/java/awt/image/PackedColorModel.java
+++ b/libjava/java/awt/image/PackedColorModel.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002 Free Software Foundation
+/* Copyright (C) 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -34,11 +34,13 @@ 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.awt.image;
+import gnu.java.awt.BitMaskExtent;
+
import java.awt.Point;
import java.awt.color.ColorSpace;
-import gnu.java.awt.BitMaskExtent;
/**
* @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
diff --git a/libjava/java/awt/image/PixelGrabber.java b/libjava/java/awt/image/PixelGrabber.java
index d6d2403399e..bcfa050f3df 100644
--- a/libjava/java/awt/image/PixelGrabber.java
+++ b/libjava/java/awt/image/PixelGrabber.java
@@ -1,39 +1,39 @@
/* PixelGrabber.java -- retrieve a subset of an image's data
- Copyright (C) 1999, 2003 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., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 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. */
+ Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.awt.image;
diff --git a/libjava/java/awt/image/RGBImageFilter.java b/libjava/java/awt/image/RGBImageFilter.java
index 819580e0057..0fd977eab67 100644
--- a/libjava/java/awt/image/RGBImageFilter.java
+++ b/libjava/java/awt/image/RGBImageFilter.java
@@ -140,28 +140,19 @@ public abstract class RGBImageFilter extends ImageFilter
@param y the y coordinate of the rectangle
@param w the width of the rectangle
@param h the height of the rectangle
- @param model the <code>ColorModel</code> used to translate the pixels
@param pixels the array of pixel values
@param offset the index of the first pixels in the <code>pixels</code> array
@param scansize the width to use in extracting pixels from the <code>pixels</code> array
*/
- public void filterRGBPixels(int x,
- int y,
- int w,
- int h,
- int[] pixels,
- int off,
- int scansize)
+ public void filterRGBPixels(int x, int y, int w, int h, int[] pixels,
+ int offset, int scansize)
{
- int xp, yp, i;
-
- i = 0;
- for( xp = x; xp < ( x + w); xp++ )
- for( yp = y; yp < (y + h); yp++ )
- {
- pixels[i] = filterRGB( xp, yp, pixels[i] );
- i++;
- }
+ for (int xp = x; xp < (x + w); xp++)
+ for (int yp = y; yp < (y + h); yp++)
+ {
+ pixels[offset] = filterRGB(xp, yp, pixels[offset]);
+ offset++;
+ }
}
diff --git a/libjava/java/awt/image/Raster.java b/libjava/java/awt/image/Raster.java
index 4fd194e2a9e..0fad4ba0acb 100644
--- a/libjava/java/awt/image/Raster.java
+++ b/libjava/java/awt/image/Raster.java
@@ -128,8 +128,8 @@ public class Raster
int w, int h, int bands,
Point location)
{
- // FIXME: Implement;
- throw new UnsupportedOperationException("not implemented yet");
+ SampleModel sm = new BandedSampleModel(dataType, w, h, bands);
+ return createWritableRaster(sm, location);
}
public static WritableRaster createBandedRaster(int dataType,
@@ -139,8 +139,9 @@ public class Raster
int[] bandOffsets,
Point location)
{
- // FIXME: Implement;
- throw new UnsupportedOperationException("not implemented yet");
+ SampleModel sm = new BandedSampleModel(dataType, w, h, scanlineStride,
+ bankIndices, bandOffsets);
+ return createWritableRaster(sm, location);
}
public static WritableRaster createPackedRaster(int dataType,
@@ -154,6 +155,35 @@ public class Raster
return createWritableRaster(sm, location);
}
+ public static WritableRaster createPackedRaster(int dataType,
+ int w, int h,
+ int bands, int bitsPerBand,
+ Point location)
+ {
+ if (bands <= 0 || (bands * bitsPerBand > getTypeBits(dataType)))
+ throw new IllegalArgumentException();
+
+ SampleModel sm;
+
+ if (bands == 1)
+ sm = new MultiPixelPackedSampleModel(dataType, w, h, bitsPerBand);
+ else
+ {
+ int[] bandMasks = new int[bands];
+ int mask = 0x1;
+ for (int bits = bitsPerBand; --bits != 0;)
+ mask = (mask << 1) | 0x1;
+ for (int i = 0; i < bands; i++)
+ {
+ bandMasks[i] = mask;
+ mask <<= bitsPerBand;
+ }
+
+ sm = new SinglePixelPackedSampleModel(dataType, w, h, bandMasks);
+ }
+ return createWritableRaster(sm, location);
+ }
+
public static WritableRaster
createInterleavedRaster(DataBuffer dataBuffer, int w, int h,
int scanlineStride, int pixelStride,
@@ -175,8 +205,10 @@ public class Raster
int[] bandOffsets,
Point location)
{
- // FIXME: Implement;
- throw new UnsupportedOperationException("not implemented yet");
+ SampleModel sm = new BandedSampleModel(dataBuffer.getDataType(),
+ w, h, scanlineStride,
+ bankIndices, bandOffsets);
+ return createWritableRaster(sm, dataBuffer, location);
}
public static WritableRaster
@@ -184,7 +216,8 @@ public class Raster
int w, int h,
int scanlineStride,
int[] bandMasks,
- Point location) {
+ Point location)
+ {
SampleModel sm =
new SinglePixelPackedSampleModel(dataBuffer.getDataType(),
w, h,
@@ -192,6 +225,19 @@ public class Raster
bandMasks);
return createWritableRaster(sm, dataBuffer, location);
}
+
+ public static WritableRaster
+ createPackedRaster(DataBuffer dataBuffer,
+ int w, int h,
+ int bitsPerPixel,
+ Point location)
+ {
+ SampleModel sm =
+ new MultiPixelPackedSampleModel(dataBuffer.getDataType(),
+ w, h,
+ bitsPerPixel);
+ return createWritableRaster(sm, dataBuffer, location);
+ }
public static Raster createRaster(SampleModel sm, DataBuffer db,
Point location)
@@ -329,6 +375,11 @@ public class Raster
return height;
}
+ public final int getNumBands()
+ {
+ return numBands;
+ }
+
public final int getNumDataElements()
{
return numDataElements;
@@ -472,5 +523,24 @@ public class Raster
return result.toString();
}
-
+
+ // Map from datatype to bits
+ private static int getTypeBits(int dataType)
+ {
+ switch (dataType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ return 8;
+ case DataBuffer.TYPE_USHORT:
+ case DataBuffer.TYPE_SHORT:
+ return 16;
+ case DataBuffer.TYPE_INT:
+ case DataBuffer.TYPE_FLOAT:
+ return 32;
+ case DataBuffer.TYPE_DOUBLE:
+ return 64;
+ default:
+ return 0;
+ }
+ }
}
diff --git a/libjava/java/awt/image/RasterOp.java b/libjava/java/awt/image/RasterOp.java
index 57961808e2e..84d47c11941 100644
--- a/libjava/java/awt/image/RasterOp.java
+++ b/libjava/java/awt/image/RasterOp.java
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2002 Free Software Foundation
+/* Copyright (C) 2000, 2002, 2004 Free Software Foundation
This file is part of GNU Classpath.
@@ -34,11 +34,12 @@ 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.awt.image;
+import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
-import java.awt.RenderingHints;
public interface RasterOp {
diff --git a/libjava/java/awt/image/RescaleOp.java b/libjava/java/awt/image/RescaleOp.java
new file mode 100644
index 00000000000..cc892b67707
--- /dev/null
+++ b/libjava/java/awt/image/RescaleOp.java
@@ -0,0 +1,218 @@
+/* Copyright (C) 2004 Free Software Foundation
+
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.awt.image;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.util.Arrays;
+
+/**
+ * @author Jerry Quinn (jlquinn@optonline.net)
+ */
+public class RescaleOp implements BufferedImageOp, RasterOp
+{
+ private float[] scale;
+ private float[] offsets;
+ private RenderingHints hints = null;
+
+ public RescaleOp(float[] scaleFactors,
+ float[] offsets,
+ RenderingHints hints)
+ {
+ this.scale = scaleFactors;
+ this.offsets = offsets;
+ this.hints = hints;
+ }
+
+ public RescaleOp(float scaleFactor,
+ float offset,
+ RenderingHints hints)
+ {
+ scale = new float[]{ scaleFactor };
+ offsets = new float[]{offset};
+ this.hints = hints;
+ }
+
+ public final float[] getScaleFactors(float[] scaleFactors)
+ {
+ if (scaleFactors == null)
+ scaleFactors = new float[scale.length];
+ System.arraycopy(scale, 0, scaleFactors, 0, scale.length);
+ return scaleFactors;
+ }
+
+ public final float[] getOffsets(float[] offsets)
+ {
+ if (offsets == null)
+ offsets = new float[this.offsets.length];
+ System.arraycopy(this.offsets, 0, offsets, 0, this.offsets.length);
+ return offsets;
+ }
+
+ public final int getNumFactors()
+ {
+ return scale.length;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getRenderingHints()
+ */
+ public RenderingHints getRenderingHints()
+ {
+ return hints;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#filter(java.awt.image.BufferedImage, java.awt.image.BufferedImage)
+ */
+ public final BufferedImage filter(BufferedImage src, BufferedImage dst)
+ {
+ // TODO Make sure premultiplied alpha is handled correctly.
+ // TODO See that color conversion is handled.
+ // TODO figure out how to use rendering hints.
+ if (scale.length != offsets.length)
+ throw new IllegalArgumentException();
+
+ ColorModel scm = src.getColorModel();
+ if (dst == null) dst = createCompatibleDestImage(src, null);
+
+ WritableRaster wsrc = src.getRaster();
+ WritableRaster wdst = dst.getRaster();
+
+ // Share constant across colors except alpha
+ if (scale.length == 1 || scale.length == scm.getNumColorComponents())
+ {
+ // Construct a raster that doesn't include an alpha band.
+ int[] subbands = new int[scm.getNumColorComponents()];
+ for (int i=0; i < subbands.length; i++) subbands[i] = i;
+ wsrc =
+ wsrc.createWritableChild(wsrc.minX, wsrc.minY, wsrc.width, wsrc.height,
+ wsrc.minX, wsrc.minY, subbands);
+ }
+ // else all color bands
+
+ filter(wsrc, wdst);
+ return dst;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#filter(java.awt.image.Raster, java.awt.image.WritableRaster)
+ */
+ public final WritableRaster filter(Raster src, WritableRaster dest)
+ {
+ if (dest == null) dest = src.createCompatibleWritableRaster();
+
+ // Required sanity checks
+ if (src.numBands != dest.numBands || scale.length != offsets.length)
+ throw new IllegalArgumentException();
+ if (scale.length != 1 && scale.length != src.numBands)
+ throw new IllegalArgumentException();
+
+ // Create scaling arrays if needed
+ float[] lscale = scale;
+ float[] loff = offsets;
+ if (scale.length == 1)
+ {
+ lscale = new float[src.numBands];
+ Arrays.fill(lscale, scale[0]);
+ loff = new float[src.numBands];
+ Arrays.fill(loff, offsets[0]);
+ }
+
+ // TODO The efficiency here can be improved for various data storage
+ // patterns, aka SampleModels.
+ float[] pixel = new float[src.numBands];
+ for (int y = src.minY; y < src.height + src.minY; y++)
+ for (int x = src.minX; x < src.width + src.minX; x++)
+ {
+ src.getPixel(x, y, pixel);
+ for (int b = 0; b < src.numBands; b++)
+ pixel[b] = pixel[b] * lscale[b] + loff[b];
+ dest.setPixel(x, y, pixel);
+ }
+ return dest;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#createCompatibleDestImage(java.awt.image.BufferedImage, java.awt.image.ColorModel)
+ */
+ public BufferedImage createCompatibleDestImage(BufferedImage src,
+ ColorModel dstCM)
+ {
+ if (dstCM == null) dstCM = src.getColorModel();
+ WritableRaster wr = src.getRaster().createCompatibleWritableRaster();
+ BufferedImage image
+ = new BufferedImage(dstCM, wr, src.isPremultiplied, null);
+ return image;
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#createCompatibleDestRaster(java.awt.image.Raster)
+ */
+ public WritableRaster createCompatibleDestRaster(Raster src)
+ {
+ return src.createCompatibleWritableRaster();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getBounds2D(java.awt.image.BufferedImage)
+ */
+ public final Rectangle2D getBounds2D(BufferedImage src)
+ {
+ return src.getRaster().getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.RasterOp#getBounds2D(java.awt.image.Raster)
+ */
+ public final Rectangle2D getBounds2D(Raster src)
+ {
+ return src.getBounds();
+ }
+
+ /* (non-Javadoc)
+ * @see java.awt.image.BufferedImageOp#getPoint2D(java.awt.geom.Point2D, java.awt.geom.Point2D)
+ */
+ public final Point2D getPoint2D(Point2D src, Point2D dst) {
+ if (dst == null) dst = (Point2D) src.clone();
+ else dst.setLocation(src);
+ return dst;
+ }
+
+}
diff --git a/libjava/java/awt/image/SampleModel.java b/libjava/java/awt/image/SampleModel.java
index a5d65ff20fe..4e3b38b9922 100644
--- a/libjava/java/awt/image/SampleModel.java
+++ b/libjava/java/awt/image/SampleModel.java
@@ -456,6 +456,17 @@ public abstract class SampleModel
public abstract SampleModel createCompatibleSampleModel(int w, int h);
+ /**
+ * Return a SampleModel with a subset of the bands in this model.
+ *
+ * Selects bands.length bands from this sample model. The bands chosen
+ * are specified in the indices of bands[]. This also permits permuting
+ * the bands as well as taking a subset. Thus, giving an array with
+ * 1, 2, 3, ..., numbands, will give an identical sample model.
+ *
+ * @param bands Array with band indices to include.
+ * @return A new sample model
+ */
public abstract SampleModel createSubsetSampleModel(int[] bands);
public abstract DataBuffer createDataBuffer();
diff --git a/libjava/java/awt/image/ShortLookupTable.java b/libjava/java/awt/image/ShortLookupTable.java
index 223d03bf53b..36beb1df540 100644
--- a/libjava/java/awt/image/ShortLookupTable.java
+++ b/libjava/java/awt/image/ShortLookupTable.java
@@ -61,7 +61,7 @@ public class ShortLookupTable extends LookupTable
*
* @param offset Offset to be subtracted.
* @param data Array of lookup tables.
- * @exception IllegalArgumentException if offset < 0 or data.length < 1.
+ * @exception IllegalArgumentException if offset &lt; 0 or data.length &lt; 1.
*/
public ShortLookupTable(int offset, short[][] data)
throws IllegalArgumentException
@@ -78,7 +78,7 @@ public class ShortLookupTable extends LookupTable
*
* @param offset Offset to be subtracted.
* @param data Lookup table for all components.
- * @exception IllegalArgumentException if offset < 0.
+ * @exception IllegalArgumentException if offset &lt; 0.
*/
public ShortLookupTable(int offset, short[] data)
throws IllegalArgumentException
@@ -107,14 +107,14 @@ public class ShortLookupTable extends LookupTable
* translation arrays.
*
* @param src Component values of a pixel.
- * @param dest Destination array for values, or null.
+ * @param dst Destination array for values, or null.
* @return Translated values for the pixel.
*/
public int[] lookupPixel(int[] src, int[] dst)
throws ArrayIndexOutOfBoundsException
{
if (dst == null)
- dst = new int[numComponents];
+ dst = new int[src.length];
if (data.length == 1)
for (int i=0; i < src.length; i++)
@@ -140,14 +140,14 @@ public class ShortLookupTable extends LookupTable
* translation arrays.
*
* @param src Component values of a pixel.
- * @param dest Destination array for values, or null.
+ * @param dst Destination array for values, or null.
* @return Translated values for the pixel.
*/
public short[] lookupPixel(short[] src, short[] dst)
throws ArrayIndexOutOfBoundsException
{
if (dst == null)
- dst = new short[numComponents];
+ dst = new short[src.length];
if (data.length == 1)
for (int i=0; i < src.length; i++)
diff --git a/libjava/java/awt/image/SinglePixelPackedSampleModel.java b/libjava/java/awt/image/SinglePixelPackedSampleModel.java
index 578500dbd0a..94a9537318e 100644
--- a/libjava/java/awt/image/SinglePixelPackedSampleModel.java
+++ b/libjava/java/awt/image/SinglePixelPackedSampleModel.java
@@ -59,6 +59,16 @@ public class SinglePixelPackedSampleModel extends SampleModel
int scanlineStride, int[] bitMasks)
{
super(dataType, w, h, bitMasks.length);
+
+ switch (dataType)
+ {
+ case DataBuffer.TYPE_BYTE:
+ case DataBuffer.TYPE_USHORT:
+ case DataBuffer.TYPE_INT:
+ break;
+ default:
+ throw new IllegalArgumentException("SinglePixelPackedSampleModel unsupported dataType");
+ }
this.scanlineStride = scanlineStride;
this.bitMasks = bitMasks;
@@ -382,7 +392,7 @@ public class SinglePixelPackedSampleModel extends SampleModel
* @param y The y-coordinate of the pixel rectangle in <code>obj</code>.
* @param w The width of the pixel rectangle in <code>obj</code>.
* @param h The height of the pixel rectangle in <code>obj</code>.
- * @param obj The primitive array containing the pixels to set.
+ * @param iArray The primitive array containing the pixels to set.
* @param data The DataBuffer to store the pixels into.
* @see java.awt.image.SampleModel#setPixels(int, int, int, int, int[], java.awt.image.DataBuffer)
*/
diff --git a/libjava/java/awt/print/Book.java b/libjava/java/awt/print/Book.java
index 19014bacf6c..9bdd7d6fd34 100644
--- a/libjava/java/awt/print/Book.java
+++ b/libjava/java/awt/print/Book.java
@@ -93,7 +93,7 @@ getNumberOfPages()
* This method returns the <code>PageFormat</code> object for the
* specified page.
*
- * @param page_numbers The number of the page to get information for, where
+ * @param page_number The number of the page to get information for, where
* page numbers start at 0.
*
* @return The <code>PageFormat</code> object for the specified page.
@@ -112,7 +112,7 @@ getPageFormat(int page_number)
* This method returns the <code>Printable</code> object for the
* specified page.
*
- * @param page_numbers The number of the page to get information for, where
+ * @param page_number The number of the page to get information for, where
* page numbers start at 0.
*
* @return The <code>Printable</code> object for the specified page.
@@ -155,11 +155,11 @@ append(Printable printable, PageFormat page_format)
* @exception NullPointerException If any argument is <code>null</code>.
*/
public void
-append(Printable painter, PageFormat page_format, int num_pages)
+append(Printable printable, PageFormat page_format, int num_pages)
{
for (int i = 0; i < num_pages; i++)
{
- printables.addElement(painter);
+ printables.addElement(printable);
page_formats.addElement(page_format);
}
}
@@ -175,7 +175,7 @@ append(Printable painter, PageFormat page_format, int num_pages)
* @param printable The new <code>Printable</code> for the page.
* @param page_format The new <code>PageFormat</code> for the page.
*
- * @param IndexOutOfBoundsException If the specified page does not exist.
+ * @throws IndexOutOfBoundsException If the specified page does not exist.
*/
public void
setPage(int page_num, Printable printable, PageFormat page_format)
@@ -183,6 +183,4 @@ setPage(int page_num, Printable printable, PageFormat page_format)
printables.setElementAt(printable, page_num);
page_formats.setElementAt(page_format, page_num);
}
-
-} // class Book
-
+}
diff --git a/libjava/java/awt/print/Printable.java b/libjava/java/awt/print/Printable.java
index fecc01a9d37..3e63211ef15 100644
--- a/libjava/java/awt/print/Printable.java
+++ b/libjava/java/awt/print/Printable.java
@@ -1,5 +1,5 @@
/* Printable.java -- Renders a page to the print device
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,56 +35,46 @@ 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.awt.print;
import java.awt.Graphics;
+
/**
- * This interface provides a mechanism for the actual printing of pages to the
- * printer. The object implementing this interface performs the page
- * rendering.
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- */
+ * This interface provides a mechanism for the actual printing of pages to the
+ * printer. The object implementing this interface performs the page
+ * rendering.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ */
public interface Printable
{
-
-/*
- * Static Variables
- */
-
-/**
- * This value is returned by the <code>print()</code> method to indicate
- * that the requested page number does not exist.
- */
-int NO_SUCH_PAGE = 0;
-
-/**
- * This value is returned by the <code>print()</code> method to indicate
- * that the requested page exists and has been printed.
- */
-int PAGE_EXISTS = 1;
-
-/*************************************************************************/
-
-/**
- * This method prints the specified page to the specified graphics
- * context in the specified format. The pages are numbered starting
- * from zero.
- *
- * @param graphics The graphics context to render the pages on.
- * @param format The format in which to print the page.
- * @param page_number The page number to print, where numbers start at zero.
- *
- * @return <code>PAGE_EXISTS</code> if the requested page exists and was
- * successfully printed, <code>NO_SUCH_PAGE</code> otherwise.
- *
- * @exception PrinterException If an error occurs during printing.
- */
-int
-print(Graphics graphics, PageFormat format, int page_number)
- throws PrinterException;
-
-} // interface Printable
-
+ /**
+ * This value is returned by the <code>print()</code> method to indicate
+ * that the requested page exists and has been printed.
+ */
+ int PAGE_EXISTS = 0;
+
+ /**
+ * This value is returned by the <code>print()</code> method to indicate
+ * that the requested page number does not exist.
+ */
+ int NO_SUCH_PAGE = 1;
+
+ /**
+ * This method prints the specified page to the specified graphics
+ * context in the specified format. The pages are numbered starting
+ * from zero.
+ *
+ * @param graphics The graphics context to render the pages on.
+ * @param format The format in which to print the page.
+ * @param page_number The page number to print, where numbers start at zero.
+ *
+ * @return <code>PAGE_EXISTS</code> if the requested page exists and was
+ * successfully printed, <code>NO_SUCH_PAGE</code> otherwise.
+ *
+ * @exception PrinterException If an error occurs during printing.
+ */
+ int print(Graphics graphics, PageFormat format, int page_number)
+ throws PrinterException;
+}
diff --git a/libjava/java/awt/print/PrinterJob.java b/libjava/java/awt/print/PrinterJob.java
index 3ad456788e4..8998aa0ff89 100644
--- a/libjava/java/awt/print/PrinterJob.java
+++ b/libjava/java/awt/print/PrinterJob.java
@@ -1,5 +1,5 @@
/* PrinterJob.java -- This job is the printer control class
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,219 +38,246 @@ exception statement from your version. */
package java.awt.print;
-/**
- * This class controls printing.
- *
- * @author Aaron M. Renn (arenn@urbanophile.com)
- */
-public abstract class PrinterJob
-{
-
-/*
- * Class Methods
- */
-
-/**
- * Creates a new print job.
- *
- * @return A <code>PrinterJob</code> object for the newly created print job.
- */
-public static PrinterJob
-getPrinterJob()
-{
- // FIXME: Need to fix this to load a default implementation instance.
- return(null);
-}
-
-/*************************************************************************/
-
-/*
- * Constructors
- */
+import javax.print.DocFlavor;
+import javax.print.PrintService;
+import javax.print.PrintServiceLookup;
+//import javax.print.StreamPrintServiceFactory;
+import javax.print.attribute.PrintRequestAttributeSet;
/**
- * Initializes a new instance of <code>PrinterJob</code>.
- */
-public
-PrinterJob()
-{
- ;
-}
-
-/*************************************************************************/
-
-/*
- * Instance Methods
+ * This class controls printing.
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
*/
-
-/**
- * Returns the number of copies to be printed.
- *
- * @return The number of copies to be printed.
- */
-public abstract int
-getCopies();
-
-/*************************************************************************/
-
-/**
- * Sets the number of copies to be printed.
- *
- * @param copies The number of copies to be printed.
- */
-public abstract void setCopies (int copies);
-
-/*************************************************************************/
-
-/**
- * Returns the name of the print job.
- *
- * @return The name of the print job.
- */
-public abstract String
-getJobName();
-
-/*************************************************************************/
-
-/**
- * Sets the name of the print job.
- *
- * @param job_name The name of the print job.
- */
-public abstract void setJobName (String job_name);
-
-/*************************************************************************/
-
-/**
- * Returns the printing user name.
- *
- * @return The printing username.
- */
-public abstract String
-getUserName();
-
-/*************************************************************************/
-
-/**
- * Cancels an in progress print job.
- */
-public abstract void
-cancel();
-
-/*************************************************************************/
-
-/**
- * Tests whether or not this job has been cancelled.
- *
- * @param <code>true</code> if this job has been cancelled, <code>false</code>
- * otherwise.
- */
-public abstract boolean
-isCancelled();
-
-/*************************************************************************/
-
-/**
- * Returns an instance of the default page which will have the default
- * paper and orientation.
- *
- * @return A default instance of <code>PageFormat</code>.
- */
-public PageFormat
-defaultPage()
+public abstract class PrinterJob
{
- return(new PageFormat());
+ // The print service associated with this job
+ private PrintService printer = null;
+
+ /**
+ * Creates a new print job.
+ *
+ * @return A <code>PrinterJob</code> object for the newly created print job.
+ */
+ public static PrinterJob getPrinterJob()
+ {
+ // FIXME: Need to fix this to load a default implementation instance.
+ return null;
+ }
+
+ /**
+ * Initializes a new instance of <code>PrinterJob</code>.
+ */
+ public PrinterJob()
+ {
+ }
+
+ /**
+ * Returns the number of copies to be printed.
+ *
+ * @return The number of copies to be printed.
+ */
+ public abstract int getCopies();
+
+ /**
+ * Sets the number of copies to be printed.
+ *
+ * @param copies The number of copies to be printed.
+ */
+ public abstract void setCopies(int copies);
+
+ /**
+ * Returns the name of the print job.
+ *
+ * @return The name of the print job.
+ */
+ public abstract String getJobName();
+
+ /**
+ * Sets the name of the print job.
+ *
+ * @param job_name The name of the print job.
+ */
+ public abstract void setJobName(String job_name);
+
+ /**
+ * Returns the printing user name.
+ *
+ * @return The printing username.
+ */
+ public abstract String getUserName();
+
+ /**
+ * Cancels an in progress print job.
+ */
+ public abstract void cancel();
+
+ /**
+ * Tests whether or not this job has been cancelled.
+ *
+ * @return <code>true</code> if this job has been cancelled, <code>false</code>
+ * otherwise.
+ */
+ public abstract boolean isCancelled();
+
+ /**
+ * Returns an instance of the default page which will have the default
+ * paper and orientation.
+ *
+ * @return A default instance of <code>PageFormat</code>.
+ */
+ public PageFormat defaultPage()
+ {
+ return new PageFormat();
+ }
+
+ /**
+ * Clones the specified <code>PageFormat</code> object then alters the
+ * clone so that it represents the default page format.
+ *
+ * @param page_format The <code>PageFormat</code> to clone.
+ *
+ * @return A new default page format.
+ */
+ public abstract PageFormat defaultPage(PageFormat page_format);
+
+ /**
+ * Displays a dialog box to the user which allows the page format
+ * attributes to be modified.
+ *
+ * @param page_format The <code>PageFormat</code> object to modify.
+ *
+ * @return The modified <code>PageFormat</code>.
+ */
+ public abstract PageFormat pageDialog(PageFormat page_format);
+
+ /**
+ * Prints the pages.
+ */
+ public abstract void print () throws PrinterException;
+
+ /**
+ * Prints the page with given attributes.
+ */
+ public abstract void print (PrintRequestAttributeSet attributes)
+ throws PrinterException;
+
+ /**
+ * Displays a dialog box to the user which allows the print job
+ * attributes to be modified.
+ *
+ * @return <code>false</code> if the user cancels the dialog box,
+ * <code>true</code> otherwise.
+ */
+ public abstract boolean printDialog();
+
+ /**
+ * Displays a dialog box to the user which allows the print job
+ * attributes to be modified.
+ *
+ * @return <code>false</code> if the user cancels the dialog box,
+ * <code>true</code> otherwise.
+ */
+ public abstract boolean printDialog(PrintRequestAttributeSet attributes);
+
+ /**
+ * This sets the pages that are to be printed.
+ *
+ * @param pageable The pages to be printed, which may not be <code>null</code>.
+ */
+ public abstract void setPageable(Pageable pageable);
+
+ /**
+ * Sets this specified <code>Printable</code> as the one to use for
+ * rendering the pages on the print device.
+ *
+ * @param printable The <code>Printable</code> for the print job.
+ */
+ public abstract void setPrintable(Printable printable);
+
+ /**
+ * Sets the <code>Printable</code> and the page format for the pages
+ * to be printed.
+ *
+ * @param printable The <code>Printable</code> for the print job.
+ * @param page_format The <code>PageFormat</code> for the print job.
+ */
+ public abstract void setPrintable(Printable printable, PageFormat page_format);
+
+ /**
+ * Makes any alterations to the specified <code>PageFormat</code>
+ * necessary to make it work with the current printer. The alterations
+ * are made to a clone of the input object, which is then returned.
+ *
+ * @param page_format The <code>PageFormat</code> to validate.
+ *
+ * @return The validated <code>PageFormat</code>.
+ */
+ public abstract PageFormat validatePage(PageFormat page_format);
+
+ /**
+ * Find and return 2D image print services.
+ *
+ * This is the same as calling PrintServiceLookup.lookupPrintServices()
+ * with Pageable service-specified DocFlavor.
+ * @return Array of PrintService objects, could be empty.
+ * @since 1.4
+ */
+ public static PrintService[] lookupPrintServices()
+ {
+ return new PrintService[0];
+ // FIXME:
+ // Enable this when javax.print has this implemented.
+// return PrintServiceLookup.lookupPrintServices(
+// new DocFlavor("application/x-java-jvm-local-objectref",
+// "java.awt.print.Pageable"),
+// null);
+ }
+
+ /**
+ * Find and return 2D image stream print services.
+ *
+ * This is the same as calling
+ * StreamPrintServiceFactory.lookupStreamPrintServices()
+ * with Pageable service-specified DocFlavor.
+ * @param mimeType The output format mime type, or null for any type.
+ * @return Array of stream print services, could be empty.
+ * @since 1.4
+ */
+ // FIXME:
+ // Enable when javax.print has StreamPrintServiceFactory
+// public static StreamPrintServiceFactory[] lookupStreamPrintServices(String mimeType)
+// {
+// return StreamPrintServiceFactory.lookupStreamServiceFactories(
+// new DocFlavor("application/x-java-jvm-local-objectref",
+// "java.awt.print.Pageable"),
+// mimeType);
+// }
+
+ /**
+ * Return the printer for this job. If print services aren't supported by
+ * the subclass, returns null.
+ *
+ * @return The associated PrintService.
+ * @since 1.4
+ */
+ public PrintService getPrintService()
+ {
+ return null;
+ }
+
+ /**
+ * Change the printer for this print job to service. Subclasses that
+ * support setting the print service override this method. Throws
+ * PrinterException when the class doesn't support setting the printer,
+ * the service doesn't support Pageable or Printable interfaces for 2D
+ * print output.
+ * @param service The new printer to use.
+ * @throws PrinterException if service is not valid.
+ */
+ public void setPrintService(PrintService service)
+ throws PrinterException
+ {
+ throw new PrinterException();
+ }
}
-
-/*************************************************************************/
-
-/**
- * Clones the specified <code>PageFormat</code> object then alters the
- * clone so that it represents the default page format.
- *
- * @param page_format The <code>PageFormat</code> to clone.
- *
- * @return A new default page format.
- */
-public abstract PageFormat
-defaultPage(PageFormat page_format);
-
-/*************************************************************************/
-
-/**
- * Displays a dialog box to the user which allows the page format
- * attributes to be modified.
- *
- * @param page_format The <code>PageFormat</code> object to modify.
- *
- * @return The modified <code>PageFormat</code>.
- */
-public abstract PageFormat
-pageDialog(PageFormat page_format);
-
-/*************************************************************************/
-
-/**
- * Prints the pages.
- */
-public abstract void print () throws PrinterException;
-
-/**
- * Displays a dialog box to the user which allows the print job
- * attributes to be modified.
- *
- * @return <code>false</code> if the user cancels the dialog box,
- * <code>true</code> otherwise.
- */
-public abstract boolean
-printDialog();
-
-/*************************************************************************/
-
-/**
- * This sets the pages that are to be printed.
- *
- * @param pageable The pages to be printed, which may not be <code>null</code>.
- */
-public abstract void
-setPageable(Pageable pageable);
-
-/*************************************************************************/
-
-/**
- * Sets this specified <code>Printable</code> as the one to use for
- * rendering the pages on the print device.
- *
- * @param printable The <code>Printable</code> for the print job.
- */
-public abstract void
-setPrintable(Printable printable);
-
-/*************************************************************************/
-
-/**
- * Sets the <code>Printable</code> and the page format for the pages
- * to be printed.
- *
- * @param printable The <code>Printable</code> for the print job.
- * @param page_format The <code>PageFormat</code> for the print job.
- */
-public abstract void
-setPrintable(Printable printable, PageFormat page_format);
-
-/*************************************************************************/
-
-/**
- * Makes any alterations to the specified <code>PageFormat</code>
- * necessary to make it work with the current printer. The alterations
- * are made to a clone of the input object, which is then returned.
- *
- * @param page_format The <code>PageFormat</code> to validate.
- *
- * @return The validated <code>PageFormat</code>.
- */
-public abstract PageFormat
-validatePage(PageFormat page);
-
-} // class PrinterJob
-