diff options
author | Graydon Hoare <graydon@redhat.com> | 2003-09-17 19:06:55 +0000 |
---|---|---|
committer | Graydon Hoare <graydon@gcc.gnu.org> | 2003-09-17 19:06:55 +0000 |
commit | 3b2d7c47c40faaf768857fdde27e18a801453d94 (patch) | |
tree | 1b8a9b7ac4a553f1917df84bf7861cd9b07999a0 /libjava/java | |
parent | eb26c76c647b9ce601f44f1c1e714875dbf9c6f4 (diff) | |
download | gcc-3b2d7c47c40faaf768857fdde27e18a801453d94.zip gcc-3b2d7c47c40faaf768857fdde27e18a801453d94.tar.gz gcc-3b2d7c47c40faaf768857fdde27e18a801453d94.tar.bz2 |
[multiple changes]
2003-09-16 Graydon Hoare <graydon@redhat.com>
* java/awt/BufferedImage.java (setData): Support non-component
sample models.
(getData): Same.
2003-09-10 Graydon Hoare <graydon@redhat.com>
* java/awt/geom/AffineTransform.java(transform): Fix airthmetic bugs.
* java/awt/geom/Arc2D.java: Approximate arc segments with cubics.
From-SVN: r71472
Diffstat (limited to 'libjava/java')
-rw-r--r-- | libjava/java/awt/geom/AffineTransform.java | 8 | ||||
-rw-r--r-- | libjava/java/awt/geom/Arc2D.java | 129 | ||||
-rw-r--r-- | libjava/java/awt/image/BufferedImage.java | 28 |
3 files changed, 110 insertions, 55 deletions
diff --git a/libjava/java/awt/geom/AffineTransform.java b/libjava/java/awt/geom/AffineTransform.java index 3c9486e..d479763 100644 --- a/libjava/java/awt/geom/AffineTransform.java +++ b/libjava/java/awt/geom/AffineTransform.java @@ -1089,7 +1089,7 @@ public class AffineTransform implements Cloneable, Serializable float x = srcPts[srcOff++]; float y = srcPts[srcOff++]; dstPts[dstOff++] = (float) (m00 * x + m01 * y + m02); - dstPts[dstOff++] = (float) (m10 * x + m10 * y + m12); + dstPts[dstOff++] = (float) (m10 * x + m11 * y + m12); } } @@ -1123,7 +1123,7 @@ public class AffineTransform implements Cloneable, Serializable double x = srcPts[srcOff++]; double y = srcPts[srcOff++]; dstPts[dstOff++] = m00 * x + m01 * y + m02; - dstPts[dstOff++] = m10 * x + m10 * y + m12; + dstPts[dstOff++] = m10 * x + m11 * y + m12; } } @@ -1148,7 +1148,7 @@ public class AffineTransform implements Cloneable, Serializable float x = srcPts[srcOff++]; float y = srcPts[srcOff++]; dstPts[dstOff++] = m00 * x + m01 * y + m02; - dstPts[dstOff++] = m10 * x + m10 * y + m12; + dstPts[dstOff++] = m10 * x + m11 * y + m12; } } @@ -1173,7 +1173,7 @@ public class AffineTransform implements Cloneable, Serializable double x = srcPts[srcOff++]; double y = srcPts[srcOff++]; dstPts[dstOff++] = (float) (m00 * x + m01 * y + m02); - dstPts[dstOff++] = (float) (m10 * x + m10 * y + m12); + dstPts[dstOff++] = (float) (m10 * x + m11 * y + m12); } } diff --git a/libjava/java/awt/geom/Arc2D.java b/libjava/java/awt/geom/Arc2D.java index 3819efe..2eb9650 100644 --- a/libjava/java/awt/geom/Arc2D.java +++ b/libjava/java/awt/geom/Arc2D.java @@ -582,11 +582,11 @@ public abstract class Arc2D extends RectangularShape limit = -1; else if (e == 0) limit = type; - else if (e <= 90) + else if (e <= Math.PI / 2.0) limit = type + 1; - else if (e <= 180) + else if (e <= Math.PI) limit = type + 2; - else if (e <= 270) + else if (e <= 3.0 * (Math.PI / 2.0)) limit = type + 3; else limit = type + 4; @@ -649,36 +649,11 @@ public abstract class Arc2D extends RectangularShape */ public int currentSegment(float[] coords) { - if (current > limit) - throw new NoSuchElementException("arc iterator out of bounds"); - if (current == 0) - { - coords[0] = (float) (Math.cos(start) * w + x) / 2; - coords[1] = (float) (Math.sin(start) * h + y) / 2; - if (xform != null) - xform.transform(coords, 0, coords, 0, 1); - return SEG_MOVETO; - } - if (type != OPEN && current == limit) - return SEG_CLOSE; - if (type == PIE && current == limit - 1) - { - coords[0] = (float) (x + w / 2); - coords[1] = (float) (y + h / 2); - if (xform != null) - xform.transform(coords, 0, coords, 0, 1); - return SEG_LINETO; - } - // XXX Fill coords with 2 control points and next quarter point - coords[0] = (float) 0; - coords[1] = (float) 0; - coords[2] = (float) 0; - coords[3] = (float) 0; - coords[4] = (float) 0; - coords[5] = (float) 0; - if (xform != null) - xform.transform(coords, 0, coords, 0, 3); - return SEG_CUBICTO; + double[] double_coords = new double[6]; + int code = currentSegment (double_coords); + for (int i = 0; i < 6; ++i) + coords[i] = (float) double_coords[i]; + return code; } /** @@ -691,35 +666,99 @@ public abstract class Arc2D extends RectangularShape */ public int currentSegment(double[] coords) { + double rx = w/2; + double ry = h/2; + double xmid = x + rx; + double ymid = y + ry; + if (current > limit) throw new NoSuchElementException("arc iterator out of bounds"); + if (current == 0) { - coords[0] = (Math.cos(start) * w + x) / 2; - coords[1] = (Math.sin(start) * h + y) / 2; + coords[0] = xmid + rx * Math.cos(start); + coords[1] = ymid - ry * Math.sin(start); if (xform != null) xform.transform(coords, 0, coords, 0, 1); return SEG_MOVETO; } + if (type != OPEN && current == limit) return SEG_CLOSE; - if (type == PIE && current == limit - 1) + + if ((current == limit - 1) && + (type == PIE) || (type == CHORD)) { - coords[0] = (float) (x + w / 2); - coords[1] = (float) (y + h / 2); + if (type == PIE) + { + coords[0] = xmid; + coords[1] = ymid; + } + else if (type == CHORD) + { + coords[0] = xmid + rx * Math.cos(start); + coords[1] = ymid - ry * Math.sin(start); + } if (xform != null) xform.transform(coords, 0, coords, 0, 1); return SEG_LINETO; } - // XXX Fill coords with 2 control points and next quarter point - coords[0] = 0; - coords[1] = 0; - coords[2] = 0; - coords[3] = 0; - coords[4] = 0; - coords[5] = 0; + + // note that this produces a cubic approximation of the arc segment, + // not a true ellipsoid. there's no ellipsoid path segment code, + // unfortunately. the cubic approximation looks about right, though. + + double kappa = (Math.sqrt(2.0) - 1.0) * (4.0 / 3.0); + double quad = (Math.PI / 2.0); + + double curr_begin = start + (current - 1) * quad; + double curr_extent = Math.min((start + extent) - curr_begin, quad); + double portion_of_a_quadrant = curr_extent / quad; + + double x0 = xmid + rx * Math.cos(curr_begin); + double y0 = ymid - ry * Math.sin(curr_begin); + + double x1 = xmid + rx * Math.cos(curr_begin + curr_extent); + double y1 = ymid - ry * Math.sin(curr_begin + curr_extent); + + AffineTransform trans = new AffineTransform (); + double [] cvec = new double[2]; + double len = kappa * portion_of_a_quadrant; + double angle = curr_begin; + + // in a hypothetical "first quadrant" setting, our first control + // vector would be sticking up, from [1,0] to [1,kappa]. + // + // let us recall however that in java2d, y coords are upside down + // from what one would consider "normal" first quadrant rules, so we + // will *subtract* the y value of this control vector from our first + // point. + + cvec[0] = 0; + cvec[1] = len; + trans.scale (rx, ry); + trans.rotate (angle); + trans.transform(cvec, 0, cvec, 0, 1); + coords[0] = x0 + cvec[0]; + coords[1] = y0 - cvec[1]; + + // control vector #2 would, ideally, be sticking out and to the + // right, in a first quadrant arc segment. again, subtraction of y. + + cvec[0] = 0; + cvec[1] = -len; + trans.rotate (curr_extent); + trans.transform(cvec, 0, cvec, 0, 1); + coords[2] = x1 + cvec[0]; + coords[3] = y1 - cvec[1]; + + // end point + coords[4] = x1; + coords[5] = y1; + if (xform != null) xform.transform(coords, 0, coords, 0, 3); + return SEG_CUBICTO; } } // class ArcIterator diff --git a/libjava/java/awt/image/BufferedImage.java b/libjava/java/awt/image/BufferedImage.java index 1fd7b9b..8c6ead2 100644 --- a/libjava/java/awt/image/BufferedImage.java +++ b/libjava/java/awt/image/BufferedImage.java @@ -267,9 +267,16 @@ public class BufferedImage extends Image raster.createWritableChild(x, y, w, h, x, y, null // same bands ); - - // Refer to ComponentDataBlitOp for optimized data blitting: - ComponentDataBlitOp.INSTANCE.filter(src, dest); + if (src.getSampleModel () instanceof ComponentSampleModel + && dest.getSampleModel () instanceof ComponentSampleModel) + // Refer to ComponentDataBlitOp for optimized data blitting: + ComponentDataBlitOp.INSTANCE.filter(src, dest); + else + { + // slower path + int samples[] = src.getPixels (x, y, w, h, (int [])null); + dest.setPixels (x, y, w, h, samples); + } return dest; } @@ -540,9 +547,18 @@ public class BufferedImage extends Image raster.createWritableChild(x, y, w, h, x, y, null // same bands ); - - // Refer to ComponentDataBlitOp for optimized data blitting: - ComponentDataBlitOp.INSTANCE.filter(src, dest); + + if (src.getSampleModel () instanceof ComponentSampleModel + && dest.getSampleModel () instanceof ComponentSampleModel) + + // Refer to ComponentDataBlitOp for optimized data blitting: + ComponentDataBlitOp.INSTANCE.filter(src, dest); + else + { + // slower path + int samples[] = src.getPixels (x, y, w, h, (int [])null); + dest.setPixels (x, y, w, h, samples); + } } public void setRGB(int x, int y, int argb) |