/hg/icedtea6: 2 new changesets

andrew at icedtea.classpath.org andrew at icedtea.classpath.org
Sun Feb 6 05:09:12 PST 2011


changeset cbf4a48aae30 in /hg/icedtea6
details: http://icedtea.classpath.org/hg/icedtea6?cmd=changeset;node=cbf4a48aae30
author: Andrew John Hughes <ahughes at redhat.com>
date: Sun Feb 06 13:02:20 2011 +0000

	S4993545: NativeInLightFixer adds asynchronousity S6637796:
	setBounds doesn't enlarge Component S6607660:
	java.awt.Container.getMouseEventTargetImpl should be invoked while
	holding the TreeLock S6607170: Focus not set by requestFocus
	S6616323: consider benefits of replacing a component array with
	other collection from the awt.Container class S6682046: Mixing code
	does not always recalculate shapes correctly when resizing
	components S6797195: Forward-port enhancements for hw/lw mixing from
	6u12 to 7 S6725214: D3D: forward-port the new pipeline from 6u10

	2011-02-06 Andrew John Hughes <ahughes at redhat.com>

	 * Makefile.am: Add patches below.
		* patches/openjdk/4993545-nativeinlightfixer.patch,
		* patches/openjdk/6607170-request_focus.patch,
		* patches/openjdk/6607660-treelock.patch,
		* patches/openjdk/6616323-component_array.patch,
		* patches/openjdk/6637796-set_bounds.patch,
		* patches/openjdk/6682046-shape_calculation.patch, New AWT
	backports from OpenJDK7.
		* patches/openjdk/6725214-direct3d-01.patch: Rejigged against
	new patches with Oracle copyrights added.
		* patches/openjdk/6797195-hw_lw_mixing.patch: New AWT backport
	from OpenJDK7.
		* NEWS: Updated.


changeset fb1fdfc2f882 in /hg/icedtea6
details: http://icedtea.classpath.org/hg/icedtea6?cmd=changeset;node=fb1fdfc2f882
author: Andrew John Hughes <ahughes at redhat.com>
date: Sun Feb 06 13:08:35 2011 +0000

	Merge


diffstat:

16 files changed, 32537 insertions(+), 11992 deletions(-)
ChangeLog                                             |   35 
Makefile.am                                           |   23 
NEWS                                                  |   12 
patches/jtreg-6929067-fix.patch                       |    2 
patches/no-static-linking.patch                       |   44 
patches/openjdk/4493128-CubicCurve2D.patch            |  213 
patches/openjdk/4645692-CubicCurve2D.solveCubic.patch |  717 
patches/openjdk/4724552-CubicCurve2D.patch            |   48 
patches/openjdk/4993545-nativeinlightfixer.patch      |  408 
patches/openjdk/6607170-request_focus.patch           |  709 
patches/openjdk/6607660-treelock.patch                |  112 
patches/openjdk/6616323-component_array.patch         | 1083 
patches/openjdk/6637796-set_bounds.patch              |  465 
patches/openjdk/6682046-shape_calculation.patch       |  506 
patches/openjdk/6725214-direct3d-01.patch             |36815 +++++++++++------
patches/openjdk/6797195-hw_lw_mixing.patch            | 3337 +

diffs (truncated from 48404 to 500 lines):

diff -r 82d83ff8b150 -r fb1fdfc2f882 ChangeLog
--- a/ChangeLog	Tue Feb 01 18:22:19 2011 +0000
+++ b/ChangeLog	Sun Feb 06 13:08:35 2011 +0000
@@ -1,3 +1,38 @@ 2011-02-01  Andrew John Hughes  <ahughes
+2011-02-06  Andrew John Hughes  <ahughes at redhat.com>
+
+	* Makefile.am: Add patches below.
+	* patches/openjdk/4993545-nativeinlightfixer.patch,
+	* patches/openjdk/6607170-request_focus.patch,
+	* patches/openjdk/6607660-treelock.patch,
+	* patches/openjdk/6616323-component_array.patch,
+	* patches/openjdk/6637796-set_bounds.patch,
+	* patches/openjdk/6682046-shape_calculation.patch,
+	New AWT backports from OpenJDK7.
+	* patches/openjdk/6725214-direct3d-01.patch:
+	Rejigged against new patches with Oracle copyrights added.
+	* patches/openjdk/6797195-hw_lw_mixing.patch:
+	New AWT backport from OpenJDK7.
+
+2011-02-03  Andrew John Hughes  <ahughes at redhat.com>
+
+	PR616, PR99:
+	* Makefile.am: Add new patch.
+	* patches/jtreg-6929067-fix.patch:
+	Link against pthread explicitly now
+	libstdc++ is no longer static.
+	* patches/no-static-linking.patch:
+	Don't statically link libstdc++ or
+	libgcc.
+	* NEWS: Updated.
+
+2011-02-01  Denis Lila <dlila at redhat.com>
+
+	* NEWS: Update with the 3 backports
+	* Makefile.am (ICEDTEA_PATCHES): Add the patches
+	* patches/openjdk/4493128-CubicCurve2D.patch: New file.
+	* patches/openjdk/4645692-CubicCurve2D.solveCubic.patch: Likewise.
+	* patches/openjdk/4724552-CubicCurve2D.patch: Likewise.
+
 2011-02-01  Andrew John Hughes  <ahughes at redhat.com>
 
 	* NEWS: Add announcements for 1.7.8,
diff -r 82d83ff8b150 -r fb1fdfc2f882 Makefile.am
--- a/Makefile.am	Tue Feb 01 18:22:19 2011 +0000
+++ b/Makefile.am	Sun Feb 06 13:08:35 2011 +0000
@@ -178,6 +178,17 @@ SECURITY_PATCHES =
 
 ICEDTEA_PATCHES = \
 	$(SECURITY_PATCHES) \
+	patches/openjdk/4993545-nativeinlightfixer.patch \
+	patches/openjdk/6637796-set_bounds.patch \
+	patches/openjdk/6607660-treelock.patch \
+	patches/openjdk/6607170-request_focus.patch \
+	patches/openjdk/6616323-component_array.patch \
+	patches/openjdk/6682046-shape_calculation.patch \
+	patches/openjdk/6797195-hw_lw_mixing.patch \
+	patches/openjdk/6725214-direct3d-01.patch \
+        patches/openjdk/6791612-opengl-jni-fix.patch \
+        patches/openjdk/6755274-glgetstring-crash.patch \
+        patches/openjdk/6984543-onscreen_rendering_resize_test.patch \
 	patches/icedtea-notice-safepoints.patch \
 	patches/icedtea-parisc-opt.patch \
 	patches/icedtea-lucene-crash.patch \
@@ -276,7 +287,11 @@ ICEDTEA_PATCHES = \
 	patches/openjdk/6736649-text_bearings.patch \
 	patches/openjdk/6797139-jbutton_truncation.patch \
 	patches/openjdk/6883341-text_bearing_exception.patch \
-	patches/jtreg-png-reader.patch
+	patches/jtreg-png-reader.patch \
+	patches/openjdk/4724552-CubicCurve2D.patch \
+	patches/openjdk/4493128-CubicCurve2D.patch \
+	patches/openjdk/4645692-CubicCurve2D.solveCubic.patch \
+	patches/no-static-linking.patch
 
 if !WITH_ALT_HSBUILD
 ICEDTEA_PATCHES += \
@@ -310,12 +325,8 @@ endif
 endif
 
 if ENABLE_XRENDER
-ICEDTEA_PATCHES += patches/openjdk/6725214-direct3d-01.patch \
-	patches/openjdk/6307603-xrender-01.patch \
+ICEDTEA_PATCHES += patches/openjdk/6307603-xrender-01.patch \
 	patches/openjdk/6961633-xrender-02.patch \
-        patches/openjdk/6791612-opengl-jni-fix.patch \
-        patches/openjdk/6755274-glgetstring-crash.patch \
-        patches/openjdk/6984543-onscreen_rendering_resize_test.patch \
 	patches/xrender-gc-cleanup.patch
 endif
 
diff -r 82d83ff8b150 -r fb1fdfc2f882 NEWS
--- a/NEWS	Tue Feb 01 18:22:19 2011 +0000
+++ b/NEWS	Sun Feb 06 13:08:35 2011 +0000
@@ -403,8 +403,20 @@ New in release 1.10 (2011-XX-XX):
   - S6736649: test/closed/javax/swing/JMenuItem/6458123/ManualBug6458123.java fails on Linux
   - S6797139: JButton title is truncating for some strings irrespective of preferred size.
   - S6883341: SWAT: jdk7-b72 swat build(2009-09-17) threw exceptions when running Java2D demo by clicking Paint ta
+  - S4493128: CubicCurve2D intersects method fails
+  - S4724552: CubicCurve2D.contains(Rectangle2D) returns true when partially contained.
+  - S4645692: CubicCurve2D.solveCubic does not return all solutions.
+  - S4993545: NativeInLightFixer adds asynchronousity
+  - S6637796: setBounds doesn't enlarge Component
+  - S6607660: java.awt.Container.getMouseEventTargetImpl should be invoked while holding the TreeLock
+  - S6607170: Focus not set by requestFocus
+  - S6616323: consider benefits of replacing a component array with other collection from the awt.Container class
+  - S6682046: Mixing code does not always recalculate shapes correctly when resizing components
+  - S6797195: Forward-port enhancements for hw/lw mixing from 6u12 to 7
+  - S6725214: D3D: forward-port the new pipeline from 6u10
 * Bug fixes
   - RH661505: JPEGs with sRGB IEC61966-2.1 color profiles have wrong colors
+  - PR616, PR99: Don't statically link libstdc++ or libgcc
 
 New in release 1.9.5 (2011-02-01):
 
diff -r 82d83ff8b150 -r fb1fdfc2f882 patches/jtreg-6929067-fix.patch
--- a/patches/jtreg-6929067-fix.patch	Tue Feb 01 18:22:19 2011 +0000
+++ b/patches/jtreg-6929067-fix.patch	Sun Feb 06 13:08:35 2011 +0000
@@ -45,7 +45,7 @@
 +gcc ${COMP_FLAG} -o invoke \
 +-L${TESTJAVA}/jre/lib/${ARCH}/client \
 +-L${TESTJAVA}/jre/lib/${ARCH}/server \
-+-ljvm -I${TESTJAVA}/include -I${TESTJAVA}/include/linux invoke.c
++-ljvm -lpthread -I${TESTJAVA}/include -I${TESTJAVA}/include/linux invoke.c
 +
  ./invoke
  exit $?
diff -r 82d83ff8b150 -r fb1fdfc2f882 patches/no-static-linking.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/no-static-linking.patch	Sun Feb 06 13:08:35 2011 +0000
@@ -0,0 +1,44 @@
+diff -r f7afe7a5e086 make/common/shared/Compiler-gcc.gmk
+--- openjdk.orig/jdk/make/common/shared/Compiler-gcc.gmk	Fri Jan 21 16:21:28 2011 -0800
++++ openjdk/jdk/make/common/shared/Compiler-gcc.gmk	Thu Feb 03 11:34:13 2011 +0000
+@@ -61,7 +61,7 @@
+   CC             = $(COMPILER_PATH)gcc
+   CPP            = $(COMPILER_PATH)gcc -E
+   # statically link libstdc++ before C++ ABI is stablized on Linux
+-  STATIC_CXX     = true
++  STATIC_CXX     = false
+   ifeq ($(STATIC_CXX),true)
+     # g++ always dynamically links libstdc++, even we use "-Wl,-Bstatic -lstdc++"
+     # We need to use gcc to statically link the C++ runtime. gcc and g++ use
+diff -r 9797bcda6c12 make/linux/makefiles/vm.make
+--- openjdk.orig/hotspot/make/linux/makefiles/vm.make	Fri Jan 21 16:20:02 2011 -0800
++++ openjdk/hotspot/make/linux/makefiles/vm.make	Thu Feb 03 15:01:10 2011 +0000
+@@ -137,15 +137,7 @@
+ vm.def: $(Res_Files) $(Obj_Files)
+ 	sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
+ 
+-ifeq ($(SHARK_BUILD), true)
+-  STATIC_CXX = false
+-else
+-  ifeq ($(ZERO_LIBARCH), ppc64)
+-    STATIC_CXX = false
+-  else
+-    STATIC_CXX = true
+-  endif
+-endif
++STATIC_CXX = false
+ 
+ ifeq ($(LINK_INTO),AOUT)
+   LIBJVM.o                 =
+diff -r 05436b84e93a make/common/shared/Compiler-gcc.gmk
+--- openjdk.orig/corba/make/common/shared/Compiler-gcc.gmk	Sat Jan 16 01:04:04 2010 +0000
++++ openjdk/corba/make/common/shared/Compiler-gcc.gmk	Thu Feb 03 16:01:37 2011 +0000
+@@ -61,7 +61,7 @@
+   CC             = $(COMPILER_PATH)gcc
+   CPP            = $(COMPILER_PATH)gcc -E
+   # statically link libstdc++ before C++ ABI is stablized on Linux
+-  STATIC_CXX     = true
++  STATIC_CXX     = false
+   ifeq ($(STATIC_CXX),true)
+     # g++ always dynamically links libstdc++, even we use "-Wl,-Bstatic -lstdc++"
+     # We need to use gcc to statically link the C++ runtime. gcc and g++ use
diff -r 82d83ff8b150 -r fb1fdfc2f882 patches/openjdk/4493128-CubicCurve2D.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/4493128-CubicCurve2D.patch	Sun Feb 06 13:08:35 2011 +0000
@@ -0,0 +1,213 @@
+--- openjdk/jdk/src/share/classes/java/awt/geom/CubicCurve2D.java.old	2011-01-31 12:38:24.340733697 -0500
++++ openjdk/jdk/src/share/classes/java/awt/geom/CubicCurve2D.java	2011-01-31 12:54:27.462601773 -0500
+@@ -1387,203 +1387,13 @@
+             return false;
+         }
+ 
+-        // Trivially accept if either endpoint is inside the rectangle
+-        // (not on its border since it may end there and not go inside)
+-        // Record where they lie with respect to the rectangle.
+-        //     -1 => left, 0 => inside, 1 => right
+-        double x1 = getX1();
+-        double y1 = getY1();
+-        int x1tag = getTag(x1, x, x+w);
+-        int y1tag = getTag(y1, y, y+h);
+-        if (x1tag == INSIDE && y1tag == INSIDE) {
+-            return true;
+-        }
+-        double x2 = getX2();
+-        double y2 = getY2();
+-        int x2tag = getTag(x2, x, x+w);
+-        int y2tag = getTag(y2, y, y+h);
+-        if (x2tag == INSIDE && y2tag == INSIDE) {
+-            return true;
+-        }
+-
+-        double ctrlx1 = getCtrlX1();
+-        double ctrly1 = getCtrlY1();
+-        double ctrlx2 = getCtrlX2();
+-        double ctrly2 = getCtrlY2();
+-        int ctrlx1tag = getTag(ctrlx1, x, x+w);
+-        int ctrly1tag = getTag(ctrly1, y, y+h);
+-        int ctrlx2tag = getTag(ctrlx2, x, x+w);
+-        int ctrly2tag = getTag(ctrly2, y, y+h);
+-
+-        // Trivially reject if all points are entirely to one side of
+-        // the rectangle.
+-        if (x1tag < INSIDE && x2tag < INSIDE &&
+-            ctrlx1tag < INSIDE && ctrlx2tag < INSIDE)
+-        {
+-            return false;       // All points left
+-        }
+-        if (y1tag < INSIDE && y2tag < INSIDE &&
+-            ctrly1tag < INSIDE && ctrly2tag < INSIDE)
+-        {
+-            return false;       // All points above
+-        }
+-        if (x1tag > INSIDE && x2tag > INSIDE &&
+-            ctrlx1tag > INSIDE && ctrlx2tag > INSIDE)
+-        {
+-            return false;       // All points right
+-        }
+-        if (y1tag > INSIDE && y2tag > INSIDE &&
+-            ctrly1tag > INSIDE && ctrly2tag > INSIDE)
+-        {
+-            return false;       // All points below
+-        }
+-
+-        // Test for endpoints on the edge where either the segment
+-        // or the curve is headed "inwards" from them
+-        // Note: These tests are a superset of the fast endpoint tests
+-        //       above and thus repeat those tests, but take more time
+-        //       and cover more cases
+-        if (inwards(x1tag, x2tag, ctrlx1tag) &&
+-            inwards(y1tag, y2tag, ctrly1tag))
+-        {
+-            // First endpoint on border with either edge moving inside
+-            return true;
+-        }
+-        if (inwards(x2tag, x1tag, ctrlx2tag) &&
+-            inwards(y2tag, y1tag, ctrly2tag))
+-        {
+-            // Second endpoint on border with either edge moving inside
+-            return true;
+-        }
+-
+-        // Trivially accept if endpoints span directly across the rectangle
+-        boolean xoverlap = (x1tag * x2tag <= 0);
+-        boolean yoverlap = (y1tag * y2tag <= 0);
+-        if (x1tag == INSIDE && x2tag == INSIDE && yoverlap) {
+-            return true;
+-        }
+-        if (y1tag == INSIDE && y2tag == INSIDE && xoverlap) {
+-            return true;
+-        }
+-
+-        // We now know that both endpoints are outside the rectangle
+-        // but the 4 points are not all on one side of the rectangle.
+-        // Therefore the curve cannot be contained inside the rectangle,
+-        // but the rectangle might be contained inside the curve, or
+-        // the curve might intersect the boundary of the rectangle.
+-
+-        double[] eqn = new double[4];
+-        double[] res = new double[4];
+-        if (!yoverlap) {
+-            // Both y coordinates for the closing segment are above or
+-            // below the rectangle which means that we can only intersect
+-            // if the curve crosses the top (or bottom) of the rectangle
+-            // in more than one place and if those crossing locations
+-            // span the horizontal range of the rectangle.
+-            fillEqn(eqn, (y1tag < INSIDE ? y : y+h), y1, ctrly1, ctrly2, y2);
+-            int num = solveCubic(eqn, res);
+-            num = evalCubic(res, num, true, true, null,
+-                            x1, ctrlx1, ctrlx2, x2);
+-            // odd counts imply the crossing was out of [0,1] bounds
+-            // otherwise there is no way for that part of the curve to
+-            // "return" to meet its endpoint
+-            return (num == 2 &&
+-                    getTag(res[0], x, x+w) * getTag(res[1], x, x+w) <= 0);
+-        }
+-
+-        // Y ranges overlap.  Now we examine the X ranges
+-        if (!xoverlap) {
+-            // Both x coordinates for the closing segment are left of
+-            // or right of the rectangle which means that we can only
+-            // intersect if the curve crosses the left (or right) edge
+-            // of the rectangle in more than one place and if those
+-            // crossing locations span the vertical range of the rectangle.
+-            fillEqn(eqn, (x1tag < INSIDE ? x : x+w), x1, ctrlx1, ctrlx2, x2);
+-            int num = solveCubic(eqn, res);
+-            num = evalCubic(res, num, true, true, null,
+-                            y1, ctrly1, ctrly2, y2);
+-            // odd counts imply the crossing was out of [0,1] bounds
+-            // otherwise there is no way for that part of the curve to
+-            // "return" to meet its endpoint
+-            return (num == 2 &&
+-                    getTag(res[0], y, y+h) * getTag(res[1], y, y+h) <= 0);
+-        }
+-
+-        // The X and Y ranges of the endpoints overlap the X and Y
+-        // ranges of the rectangle, now find out how the endpoint
+-        // line segment intersects the Y range of the rectangle
+-        double dx = x2 - x1;
+-        double dy = y2 - y1;
+-        double k = y2 * x1 - x2 * y1;
+-        int c1tag, c2tag;
+-        if (y1tag == INSIDE) {
+-            c1tag = x1tag;
+-        } else {
+-            c1tag = getTag((k + dx * (y1tag < INSIDE ? y : y+h)) / dy, x, x+w);
+-        }
+-        if (y2tag == INSIDE) {
+-            c2tag = x2tag;
+-        } else {
+-            c2tag = getTag((k + dx * (y2tag < INSIDE ? y : y+h)) / dy, x, x+w);
+-        }
+-        // If the part of the line segment that intersects the Y range
+-        // of the rectangle crosses it horizontally - trivially accept
+-        if (c1tag * c2tag <= 0) {
+-            return true;
+-        }
+-
+-        // Now we know that both the X and Y ranges intersect and that
+-        // the endpoint line segment does not directly cross the rectangle.
+-        //
+-        // We can almost treat this case like one of the cases above
+-        // where both endpoints are to one side, except that we may
+-        // get one or three intersections of the curve with the vertical
+-        // side of the rectangle.  This is because the endpoint segment
+-        // accounts for the other intersection in an even pairing.  Thus,
+-        // with the endpoint crossing we end up with 2 or 4 total crossings.
+-        //
+-        // (Remember there is overlap in both the X and Y ranges which
+-        //  means that the segment itself must cross at least one vertical
+-        //  edge of the rectangle - in particular, the "near vertical side"
+-        //  - leaving an odd number of intersections for the curve.)
+-        //
+-        // Now we calculate the y tags of all the intersections on the
+-        // "near vertical side" of the rectangle.  We will have one with
+-        // the endpoint segment, and one or three with the curve.  If
+-        // any pair of those vertical intersections overlap the Y range
+-        // of the rectangle, we have an intersection.  Otherwise, we don't.
+-
+-        // c1tag = vertical intersection class of the endpoint segment
+-        //
+-        // Choose the y tag of the endpoint that was not on the same
+-        // side of the rectangle as the subsegment calculated above.
+-        // Note that we can "steal" the existing Y tag of that endpoint
+-        // since it will be provably the same as the vertical intersection.
+-        c1tag = ((c1tag * x1tag <= 0) ? y1tag : y2tag);
+-
+-        // Now we have to calculate an array of solutions of the curve
+-        // with the "near vertical side" of the rectangle.  Then we
+-        // need to sort the tags and do a pairwise range test to see
+-        // if either of the pairs of crossings spans the Y range of
+-        // the rectangle.
+-        //
+-        // Note that the c2tag can still tell us which vertical edge
+-        // to test against.
+-        fillEqn(eqn, (c2tag < INSIDE ? x : x+w), x1, ctrlx1, ctrlx2, x2);
+-        int num = solveCubic(eqn, res);
+-        num = evalCubic(res, num, true, true, null, y1, ctrly1, ctrly2, y2);
+-
+-        // Now put all of the tags into a bucket and sort them.  There
+-        // is an intersection iff one of the pairs of tags "spans" the
+-        // Y range of the rectangle.
+-        int tags[] = new int[num+1];
+-        for (int i = 0; i < num; i++) {
+-            tags[i] = getTag(res[i], y, y+h);
+-        }
+-        tags[num] = c1tag;
+-        Arrays.sort(tags);
+-        return ((num >= 1 && tags[0] * tags[1] <= 0) ||
+-                (num >= 3 && tags[2] * tags[3] <= 0));
++        int numCrossings = rectCrossings(x, y, w, h);
++        // the intended return value is
++        // numCrossings != 0 || numCrossings == Curve.RECT_INTERSECTS
++        // but if (numCrossings != 0) numCrossings == INTERSECTS won't matter
++        // and if !(numCrossings != 0) then numCrossings == 0, so
++        // numCrossings != RECT_INTERSECT
++        return numCrossings != 0;
+     }
+ 
+     /**
diff -r 82d83ff8b150 -r fb1fdfc2f882 patches/openjdk/4645692-CubicCurve2D.solveCubic.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/4645692-CubicCurve2D.solveCubic.patch	Sun Feb 06 13:08:35 2011 +0000
@@ -0,0 +1,717 @@
+diff -Nr --unified=3 ./openjdk.old/jdk/src/share/classes/java/awt/geom/CubicCurve2D.java ./openjdk/jdk/src/share/classes/java/awt/geom/CubicCurve2D.java
+--- ./openjdk.old/jdk/src/share/classes/java/awt/geom/CubicCurve2D.java	2011-02-01 10:52:21.560149275 -0500
++++ ./openjdk/jdk/src/share/classes/java/awt/geom/CubicCurve2D.java	2011-02-01 10:52:37.112148647 -0500
+@@ -31,6 +31,10 @@
+ import java.io.Serializable;
+ import sun.awt.geom.Curve;
+ 
++import static java.lang.Math.abs;
++import static java.lang.Math.max;
++import static java.lang.Math.ulp;
++
+ /**
+  * The <code>CubicCurve2D</code> class defines a cubic parametric curve
+  * segment in {@code (x,y)} coordinate space.
+@@ -1083,95 +1087,286 @@
+      * @since 1.3
+      */
+     public static int solveCubic(double eqn[], double res[]) {
+-        // From Numerical Recipes, 5.6, Quadratic and Cubic Equations
+-        double d = eqn[3];
+-        if (d == 0.0) {
+-            // The cubic has degenerated to quadratic (or line or ...).
++        // From Graphics Gems:
++        // http://tog.acm.org/resources/GraphicsGems/gems/Roots3And4.c
++        final double d = eqn[3];
++        if (d == 0) {
+             return QuadCurve2D.solveQuadratic(eqn, res);
+         }
+-        double a = eqn[2] / d;
+-        double b = eqn[1] / d;
+-        double c = eqn[0] / d;
+-        int roots = 0;
+-        double Q = (a * a - 3.0 * b) / 9.0;
+-        double R = (2.0 * a * a * a - 9.0 * a * b + 27.0 * c) / 54.0;
+-        double R2 = R * R;
+-        double Q3 = Q * Q * Q;
+-        a = a / 3.0;
+-        if (R2 < Q3) {
+-            double theta = Math.acos(R / Math.sqrt(Q3));
+-            Q = -2.0 * Math.sqrt(Q);
++
++        /* normal form: x^3 + Ax^2 + Bx + C = 0 */
++        final double A = eqn[2] / d;
++        final double B = eqn[1] / d;
++        final double C = eqn[0] / d;
++
++
++        //  substitute x = y - A/3 to eliminate quadratic term:
++        //     x^3 +Px + Q = 0
++        //
++        // Since we actually need P/3 and Q/2 for all of the
++        // calculations that follow, we will calculate
++        // p = P/3
++        // q = Q/2
++        // instead and use those values for simplicity of the code.
++        double sq_A = A * A;
++        double p = 1.0/3 * (-1.0/3 * sq_A + B);
++        double q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C);
++
++        /* use Cardano's formula */
++
++        double cb_p = p * p * p;
++        double D = q * q + cb_p;
++
++        final double sub = 1.0/3 * A;
++
++        int num;
++        if (D < 0) { /* Casus irreducibilis: three real solutions */
++            // see: http://en.wikipedia.org/wiki/Cubic_function#Trigonometric_.28and_hyperbolic.29_method
++            double phi = 1.0/3 * Math.acos(-q / Math.sqrt(-cb_p));
++            double t = 2 * Math.sqrt(-p);
++
+             if (res == eqn) {
+-                // Copy the eqn so that we don't clobber it with the
+-                // roots.  This is needed so that fixRoots can do its
+-                // work with the original equation.
+-                eqn = new double[4];
+-                System.arraycopy(res, 0, eqn, 0, 4);
++                eqn = Arrays.copyOf(eqn, 4);
+             }
+-            res[roots++] = Q * Math.cos(theta / 3.0) - a;
+-            res[roots++] = Q * Math.cos((theta + Math.PI * 2.0)/ 3.0) - a;
+-            res[roots++] = Q * Math.cos((theta - Math.PI * 2.0)/ 3.0) - a;
+-            fixRoots(res, eqn);
+-        } else {
+-            boolean neg = (R < 0.0);
+-            double S = Math.sqrt(R2 - Q3);
+-            if (neg) {
+-                R = -R;
++
++            res[ 0 ] =  ( t * Math.cos(phi));
++            res[ 1 ] =  (-t * Math.cos(phi + Math.PI / 3));
++            res[ 2 ] =  (-t * Math.cos(phi - Math.PI / 3));
++            num = 3;
++
++            for (int i = 0; i < num; ++i) {
++                res[ i ] -= sub;
+             }
+-            double A = Math.pow(R + S, 1.0 / 3.0);
+-            if (!neg) {
+-                A = -A;
++
++        } else {
++            // Please see the comment in fixRoots marked 'XXX' before changing
++            // any of the code in this case.



More information about the distro-pkg-dev mailing list