gcc/libjava/java/awt/geom/Area.java
Graydon Hoare ea28b8f60f 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
2004-11-30 23:59:12 +00:00

3310 lines
81 KiB
Java

/* Area.java -- represents a shape built by constructive area geometry
Copyright (C) 2002, 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.geom;
import java.awt.Rectangle;
import java.awt.Shape;
import java.util.Vector;
/**
* 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);
}
/**
* 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)
{
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);
}
/**
* 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)
{
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);
}
/**
* 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)
{
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);
}
/**
* 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)
{
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()
{
solids = new Vector();
holes = new Vector();
}
/**
* Returns whether this area encloses any area.
* @return true if the object encloses any area.
*/
public boolean isEmpty()
{
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()
{
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()
{
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()
{
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()
{
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();
}
/**
* Create a new area of the same run-time type with the same contents as
* this one.
*
* @return the clone
*/
public Object clone()
{
try
{
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
}
}
/**
* 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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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