提交 7eb62a78 编写于 作者: J jgodinez

Merge

......@@ -49,9 +49,11 @@ import java.beans.ConstructorProperties;
* from the focus point to the circumference will thus span all the gradient
* colors.
* <p>
* Specifying a focus point outside of the circle's radius will result in the
* focus being set to the intersection point of the focus-center line and the
* perimeter of the circle.
* Specifying a focus point outside of the radius of the circle will cause
* the rings of the gradient pattern to be centered on the point just inside
* the edge of the circle in the direction of the focus point.
* The rendering will internally use this modified location as if it were
* the specified focus point.
* <p>
* The user must provide an array of floats specifying how to distribute the
* colors along the gradient. These values should range from 0.0 to 1.0 and
......@@ -621,6 +623,11 @@ public final class RadialGradientPaint extends MultipleGradientPaint {
/**
* Returns a copy of the focus point of the radial gradient.
* Note that if the focus point specified when the radial gradient
* was constructed lies outside of the radius of the circle, this
* method will still return the original focus point even though
* the rendering may center the rings of color on a different
* point that lies inside the radius.
*
* @return a {@code Point2D} object that is a copy of the focus point
*/
......
......@@ -681,7 +681,7 @@ public abstract class Arc2D extends RectangularShape {
* @see java.awt.geom.Arc2D.Float
* @see java.awt.geom.Arc2D.Double
*/
Arc2D() {
protected Arc2D() {
this(OPEN);
}
......
......@@ -732,7 +732,7 @@ public abstract class Path2D implements Shape, Cloneable {
*
* @since 1.6
*/
public PathIterator getPathIterator(AffineTransform at) {
public final PathIterator getPathIterator(AffineTransform at) {
if (at == null) {
return new CopyIterator(this);
} else {
......@@ -1461,7 +1461,7 @@ public abstract class Path2D implements Shape, Cloneable {
* of this {@code Shape}'s outline
* @since 1.6
*/
public PathIterator getPathIterator(AffineTransform at) {
public final PathIterator getPathIterator(AffineTransform at) {
if (at == null) {
return new CopyIterator(this);
} else {
......@@ -2342,8 +2342,8 @@ public abstract class Path2D implements Shape, Cloneable {
*
* @since 1.6
*/
public PathIterator getPathIterator(AffineTransform at,
double flatness)
public final PathIterator getPathIterator(AffineTransform at,
double flatness)
{
return new FlatteningPathIterator(getPathIterator(at), flatness);
}
......
......@@ -27,6 +27,8 @@ package sun.java2d.pisces;
import java.util.Arrays;
import java.util.Iterator;
import static java.lang.Math.ulp;
import static java.lang.Math.sqrt;
import sun.awt.geom.PathConsumer2D;
......@@ -130,7 +132,7 @@ final class Stroker implements PathConsumer2D {
private static void computeOffset(final float lx, final float ly,
final float w, final float[] m)
{
final float len = (float)Math.sqrt(lx*lx + ly*ly);
final float len = (float) sqrt(lx*lx + ly*ly);
if (len == 0) {
m[0] = m[1] = 0;
} else {
......@@ -217,7 +219,7 @@ final class Stroker implements PathConsumer2D {
// this normal's length is at least 0.5 and at most sqrt(2)/2 (because
// we know the angle of the arc is > 90 degrees).
float nx = my - omy, ny = omx - mx;
float nlen = (float)Math.sqrt(nx*nx + ny*ny);
float nlen = (float) sqrt(nx*nx + ny*ny);
float scale = lineWidth2/nlen;
float mmx = nx * scale, mmy = ny * scale;
......@@ -246,8 +248,8 @@ final class Stroker implements PathConsumer2D {
// define the bezier curve we're computing.
// It is computed using the constraints that P1-P0 and P3-P2 are parallel
// to the arc tangents at the endpoints, and that |P1-P0|=|P3-P2|.
float cv = (float)((4.0 / 3.0) * Math.sqrt(0.5-cosext2) /
(1.0 + Math.sqrt(cosext2+0.5)));
float cv = (float) ((4.0 / 3.0) * sqrt(0.5-cosext2) /
(1.0 + sqrt(cosext2+0.5)));
// if clockwise, we need to negate cv.
if (rev) { // rev is equivalent to isCW(omx, omy, mx, my)
cv = -cv;
......@@ -284,28 +286,20 @@ final class Stroker implements PathConsumer2D {
false);
}
// Return the intersection point of the lines (x0, y0) -> (x1, y1)
// and (x0p, y0p) -> (x1p, y1p) in m[0] and m[1]
private void computeMiter(final float x0, final float y0,
final float x1, final float y1,
final float x0p, final float y0p,
final float x1p, final float y1p,
final float[] m, int off)
// Put the intersection point of the lines (x0, y0) -> (x1, y1)
// and (x0p, y0p) -> (x1p, y1p) in m[off] and m[off+1].
// If the lines are parallel, it will put a non finite number in m.
private void computeIntersection(final float x0, final float y0,
final float x1, final float y1,
final float x0p, final float y0p,
final float x1p, final float y1p,
final float[] m, int off)
{
float x10 = x1 - x0;
float y10 = y1 - y0;
float x10p = x1p - x0p;
float y10p = y1p - y0p;
// if this is 0, the lines are parallel. If they go in the
// same direction, there is no intersection so m[off] and
// m[off+1] will contain infinity, so no miter will be drawn.
// If they go in the same direction that means that the start of the
// current segment and the end of the previous segment have the same
// tangent, in which case this method won't even be involved in
// miter drawing because it won't be called by drawMiter (because
// (mx == omx && my == omy) will be true, and drawMiter will return
// immediately).
float den = x10*y10p - x10p*y10;
float t = x10p*(y0-y0p) - y10p*(x0-x0p);
t /= den;
......@@ -321,7 +315,8 @@ final class Stroker implements PathConsumer2D {
{
if ((mx == omx && my == omy) ||
(pdx == 0 && pdy == 0) ||
(dx == 0 && dy == 0)) {
(dx == 0 && dy == 0))
{
return;
}
......@@ -332,12 +327,17 @@ final class Stroker implements PathConsumer2D {
my = -my;
}
computeMiter((x0 - pdx) + omx, (y0 - pdy) + omy, x0 + omx, y0 + omy,
(dx + x0) + mx, (dy + y0) + my, x0 + mx, y0 + my,
miter, 0);
computeIntersection((x0 - pdx) + omx, (y0 - pdy) + omy, x0 + omx, y0 + omy,
(dx + x0) + mx, (dy + y0) + my, x0 + mx, y0 + my,
miter, 0);
float lenSq = (miter[0]-x0)*(miter[0]-x0) + (miter[1]-y0)*(miter[1]-y0);
// If the lines are parallel, lenSq will be either NaN or +inf
// (actually, I'm not sure if the latter is possible. The important
// thing is that -inf is not possible, because lenSq is a square).
// For both of those values, the comparison below will fail and
// no miter will be drawn, which is correct.
if (lenSq < miterLimitSq) {
emitLineTo(miter[0], miter[1], rev);
}
......@@ -566,8 +566,8 @@ final class Stroker implements PathConsumer2D {
// if p1 == p2 && p3 == p4: draw line from p1->p4, unless p1 == p4,
// in which case ignore if p1 == p2
final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * Math.ulp(y2));
final boolean p3eqp4 = within(x3,y3,x4,y4, 6 * Math.ulp(y4));
final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * ulp(y2));
final boolean p3eqp4 = within(x3,y3,x4,y4, 6 * ulp(y4));
if (p1eqp2 && p3eqp4) {
getLineOffsets(x1, y1, x4, y4, leftOff, rightOff);
return 4;
......@@ -583,7 +583,7 @@ final class Stroker implements PathConsumer2D {
float dotsq = (dx1 * dx4 + dy1 * dy4);
dotsq = dotsq * dotsq;
float l1sq = dx1 * dx1 + dy1 * dy1, l4sq = dx4 * dx4 + dy4 * dy4;
if (Helpers.within(dotsq, l1sq * l4sq, 4 * Math.ulp(dotsq))) {
if (Helpers.within(dotsq, l1sq * l4sq, 4 * ulp(dotsq))) {
getLineOffsets(x1, y1, x4, y4, leftOff, rightOff);
return 4;
}
......@@ -693,8 +693,6 @@ final class Stroker implements PathConsumer2D {
return 8;
}
// compute offset curves using bezier spline through t=0.5 (i.e.
// ComputedCurve(0.5) == IdealParallelCurve(0.5))
// return the kind of curve in the right and left arrays.
private int computeOffsetQuad(float[] pts, final int off,
float[] leftOff, float[] rightOff)
......@@ -703,58 +701,69 @@ final class Stroker implements PathConsumer2D {
final float x2 = pts[off + 2], y2 = pts[off + 3];
final float x3 = pts[off + 4], y3 = pts[off + 5];
float dx3 = x3 - x2;
float dy3 = y3 - y2;
float dx1 = x2 - x1;
float dy1 = y2 - y1;
final float dx3 = x3 - x2;
final float dy3 = y3 - y2;
final float dx1 = x2 - x1;
final float dy1 = y2 - y1;
// if p1=p2 or p3=p4 it means that the derivative at the endpoint
// vanishes, which creates problems with computeOffset. Usually
// this happens when this stroker object is trying to winden
// a curve with a cusp. What happens is that curveTo splits
// the input curve at the cusp, and passes it to this function.
// because of inaccuracies in the splitting, we consider points
// equal if they're very close to each other.
// if p1 == p2 && p3 == p4: draw line from p1->p4, unless p1 == p4,
// in which case ignore.
final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * Math.ulp(y2));
final boolean p2eqp3 = within(x2,y2,x3,y3, 6 * Math.ulp(y3));
if (p1eqp2 || p2eqp3) {
getLineOffsets(x1, y1, x3, y3, leftOff, rightOff);
return 4;
}
// if p2-p1 and p4-p3 are parallel, that must mean this curve is a line
float dotsq = (dx1 * dx3 + dy1 * dy3);
dotsq = dotsq * dotsq;
float l1sq = dx1 * dx1 + dy1 * dy1, l3sq = dx3 * dx3 + dy3 * dy3;
if (Helpers.within(dotsq, l1sq * l3sq, 4 * Math.ulp(dotsq))) {
getLineOffsets(x1, y1, x3, y3, leftOff, rightOff);
return 4;
}
// this computes the offsets at t=0, 0.5, 1, using the property that
// for any bezier curve the vectors p2-p1 and p4-p3 are parallel to
// the (dx/dt, dy/dt) vectors at the endpoints.
// this computes the offsets at t = 0, 1
computeOffset(dx1, dy1, lineWidth2, offset[0]);
computeOffset(dx3, dy3, lineWidth2, offset[1]);
float x1p = x1 + offset[0][0]; // start
float y1p = y1 + offset[0][1]; // point
float x3p = x3 + offset[1][0]; // end
float y3p = y3 + offset[1][1]; // point
computeMiter(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, leftOff, 2);
leftOff[0] = x1p; leftOff[1] = y1p;
leftOff[4] = x3p; leftOff[5] = y3p;
x1p = x1 - offset[0][0]; y1p = y1 - offset[0][1];
x3p = x3 - offset[1][0]; y3p = y3 - offset[1][1];
computeMiter(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, rightOff, 2);
rightOff[0] = x1p; rightOff[1] = y1p;
rightOff[4] = x3p; rightOff[5] = y3p;
leftOff[0] = x1 + offset[0][0]; leftOff[1] = y1 + offset[0][1];
leftOff[4] = x3 + offset[1][0]; leftOff[5] = y3 + offset[1][1];
rightOff[0] = x1 - offset[0][0]; rightOff[1] = y1 - offset[0][1];
rightOff[4] = x3 - offset[1][0]; rightOff[5] = y3 - offset[1][1];
float x1p = leftOff[0]; // start
float y1p = leftOff[1]; // point
float x3p = leftOff[4]; // end
float y3p = leftOff[5]; // point
// Corner cases:
// 1. If the two control vectors are parallel, we'll end up with NaN's
// in leftOff (and rightOff in the body of the if below), so we'll
// do getLineOffsets, which is right.
// 2. If the first or second two points are equal, then (dx1,dy1)==(0,0)
// or (dx3,dy3)==(0,0), so (x1p, y1p)==(x1p+dx1, y1p+dy1)
// or (x3p, y3p)==(x3p-dx3, y3p-dy3), which means that
// computeIntersection will put NaN's in leftOff and right off, and
// we will do getLineOffsets, which is right.
computeIntersection(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, leftOff, 2);
float cx = leftOff[2];
float cy = leftOff[3];
if (!(isFinite(cx) && isFinite(cy))) {
// maybe the right path is not degenerate.
x1p = rightOff[0];
y1p = rightOff[1];
x3p = rightOff[4];
y3p = rightOff[5];
computeIntersection(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, rightOff, 2);
cx = rightOff[2];
cy = rightOff[3];
if (!(isFinite(cx) && isFinite(cy))) {
// both are degenerate. This curve is a line.
getLineOffsets(x1, y1, x3, y3, leftOff, rightOff);
return 4;
}
// {left,right}Off[0,1,4,5] are already set to the correct values.
leftOff[2] = 2*x2 - cx;
leftOff[3] = 2*y2 - cy;
return 6;
}
// rightOff[2,3] = (x2,y2) - ((left_x2, left_y2) - (x2, y2))
// == 2*(x2, y2) - (left_x2, left_y2)
rightOff[2] = 2*x2 - cx;
rightOff[3] = 2*y2 - cy;
return 6;
}
private static boolean isFinite(float x) {
return (Float.NEGATIVE_INFINITY < x && x < Float.POSITIVE_INFINITY);
}
// This is where the curve to be processed is put. We give it
// enough room to store 2 curves: one for the current subdivision, the
// other for the rest of the curve.
......@@ -812,12 +821,12 @@ final class Stroker implements PathConsumer2D {
// if these vectors are too small, normalize them, to avoid future
// precision problems.
if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) {
float len = (float)Math.sqrt(dxs*dxs + dys*dys);
float len = (float) sqrt(dxs*dxs + dys*dys);
dxs /= len;
dys /= len;
}
if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) {
float len = (float)Math.sqrt(dxf*dxf + dyf*dyf);
float len = (float) sqrt(dxf*dxf + dyf*dyf);
dxf /= len;
dyf /= len;
}
......@@ -834,7 +843,6 @@ final class Stroker implements PathConsumer2D {
while(it.hasNext()) {
int curCurveOff = it.next();
kind = 0;
switch (type) {
case 8:
kind = computeOffsetCubic(middle, curCurveOff, lp, rp);
......@@ -843,24 +851,22 @@ final class Stroker implements PathConsumer2D {
kind = computeOffsetQuad(middle, curCurveOff, lp, rp);
break;
}
if (kind != 0) {
emitLineTo(lp[0], lp[1]);
switch(kind) {
case 8:
emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false);
emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true);
break;
case 6:
emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false);
emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true);
break;
case 4:
emitLineTo(lp[2], lp[3]);
emitLineTo(rp[0], rp[1], true);
break;
}
emitLineTo(rp[kind - 2], rp[kind - 1], true);
emitLineTo(lp[0], lp[1]);
switch(kind) {
case 8:
emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false);
emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true);
break;
case 6:
emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false);
emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true);
break;
case 4:
emitLineTo(lp[2], lp[3]);
emitLineTo(rp[0], rp[1], true);
break;
}
emitLineTo(rp[kind - 2], rp[kind - 1], true);
}
this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2;
......@@ -887,7 +893,7 @@ final class Stroker implements PathConsumer2D {
// we rotate it so that the first vector in the control polygon is
// parallel to the x-axis. This will ensure that rotated quarter
// circles won't be subdivided.
final float hypot = (float)Math.sqrt(x12 * x12 + y12 * y12);
final float hypot = (float) sqrt(x12 * x12 + y12 * y12);
final float cos = x12 / hypot;
final float sin = y12 / hypot;
final float x1 = cos * pts[0] + sin * pts[1];
......@@ -976,12 +982,12 @@ final class Stroker implements PathConsumer2D {
// if these vectors are too small, normalize them, to avoid future
// precision problems.
if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) {
float len = (float)Math.sqrt(dxs*dxs + dys*dys);
float len = (float) sqrt(dxs*dxs + dys*dys);
dxs /= len;
dys /= len;
}
if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) {
float len = (float)Math.sqrt(dxf*dxf + dyf*dyf);
float len = (float) sqrt(dxf*dxf + dyf*dyf);
dxf /= len;
dyf /= len;
}
......@@ -999,20 +1005,18 @@ final class Stroker implements PathConsumer2D {
int curCurveOff = it.next();
kind = computeOffsetCubic(middle, curCurveOff, lp, rp);
if (kind != 0) {
emitLineTo(lp[0], lp[1]);
switch(kind) {
case 8:
emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false);
emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true);
break;
case 4:
emitLineTo(lp[2], lp[3]);
emitLineTo(rp[0], rp[1], true);
break;
}
emitLineTo(rp[kind - 2], rp[kind - 1], true);
emitLineTo(lp[0], lp[1]);
switch(kind) {
case 8:
emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false);
emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true);
break;
case 4:
emitLineTo(lp[2], lp[3]);
emitLineTo(rp[0], rp[1], true);
break;
}
emitLineTo(rp[kind - 2], rp[kind - 1], true);
}
this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2;
......@@ -1050,12 +1054,12 @@ final class Stroker implements PathConsumer2D {
// if these vectors are too small, normalize them, to avoid future
// precision problems.
if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) {
float len = (float)Math.sqrt(dxs*dxs + dys*dys);
float len = (float) sqrt(dxs*dxs + dys*dys);
dxs /= len;
dys /= len;
}
if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) {
float len = (float)Math.sqrt(dxf*dxf + dyf*dyf);
float len = (float) sqrt(dxf*dxf + dyf*dyf);
dxf /= len;
dyf /= len;
}
......@@ -1073,20 +1077,18 @@ final class Stroker implements PathConsumer2D {
int curCurveOff = it.next();
kind = computeOffsetQuad(middle, curCurveOff, lp, rp);
if (kind != 0) {
emitLineTo(lp[0], lp[1]);
switch(kind) {
case 6:
emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false);
emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true);
break;
case 4:
emitLineTo(lp[2], lp[3]);
emitLineTo(rp[0], rp[1], true);
break;
}
emitLineTo(rp[kind - 2], rp[kind - 1], true);
emitLineTo(lp[0], lp[1]);
switch(kind) {
case 6:
emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false);
emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true);
break;
case 4:
emitLineTo(lp[2], lp[3]);
emitLineTo(rp[0], rp[1], true);
break;
}
emitLineTo(rp[kind - 2], rp[kind - 1], true);
}
this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2;
......
......@@ -70,7 +70,7 @@
/* avoid extra function call in case we use fread (TVT) */
#define READ(_gif,_buf,_len) \
(((GifFilePrivateType*)_gif->Private)->Read ? \
((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \
(size_t)((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \
fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File))
static int DGifGetWord(GifFileType *GifFile, int *Word);
......
......@@ -55,13 +55,15 @@ typedef Int32 hsFixed;
typedef Int32 hsFract;
typedef UInt32 Bool32;
#ifndef __cplusplus
#ifndef false
#define false 0
#define false 0
#endif
#ifndef true
#define true 1
#endif
#endif
#define kPosInfinity32 (0x7fffffff)
#define kNegInfinity32 (0x80000000)
......
......@@ -162,7 +162,7 @@ static le_int32 decompose(LEUnicode syllable, LEUnicode &lead, LEUnicode &vowel,
return 0;
}
lead = LJMO_FIRST + (sIndex / HSYL_LVCNT);
lead = (LEUnicode)(LJMO_FIRST + (sIndex / HSYL_LVCNT));
vowel = VJMO_FIRST + (sIndex % HSYL_LVCNT) / TJMO_COUNT;
trail = TJMO_FIRST + (sIndex % TJMO_COUNT);
......
......@@ -65,9 +65,9 @@ void MPreFixups::add(le_int32 baseIndex, le_int32 mpreIndex)
}
}
void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& success)
void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& leSuccess)
{
if (LE_FAILURE(success)) {
if (LE_FAILURE(leSuccess)) {
return;
}
......
......@@ -256,9 +256,9 @@ public class FcFontConfiguration extends FontConfiguration {
}
if (installedFallbackFontFiles != null) {
System.arraycopy(fileNames, index,
installedFallbackFontFiles,
0, installedFallbackFontFiles.length);
System.arraycopy(installedFallbackFontFiles, 0,
fileNames, fcFonts.length,
installedFallbackFontFiles.length);
}
result[fontIndex * NUM_STYLES + styleIndex]
......
......@@ -1107,7 +1107,8 @@ Java_sun_font_FontConfigManager_getFontConfig
arrlen = (*env)->GetArrayLength(env, fcCompFontArray);
for (i=0; i<arrlen; i++) {
FcFontSet* fontset;
int fn, j, fontCount, nfonts, minGlyphs;
int fn, j, fontCount, nfonts;
unsigned int minGlyphs;
FcChar8 **family, **styleStr, **fullname, **file;
jarray fcFontArr;
......
......@@ -235,7 +235,7 @@ static int CALLBACK EnumFontFacesInFamilyProcW(
}
fullname = (*env)->NewString(env, lpelfe->elfFullName,
wcslen((LPWSTR)lpelfe->elfFullName));
(jsize)wcslen((LPWSTR)lpelfe->elfFullName));
fullnameLC = (*env)->CallObjectMethod(env, fullname,
fmi->toLowerCaseMID, fmi->locale);
(*env)->CallBooleanMethod(env, fmi->list, fmi->addMID, fullname);
......@@ -314,7 +314,7 @@ static int CALLBACK EnumFamilyNamesW(
GdiFontMapInfo *fmi = (GdiFontMapInfo*)lParam;
JNIEnv *env = fmi->env;
jstring familyLC;
int slen;
size_t slen;
LOGFONTW lfw;
/* Both Vista and XP return DEVICE_FONTTYPE for OTF fonts */
......@@ -336,7 +336,7 @@ static int CALLBACK EnumFamilyNamesW(
return 1;
}
slen = wcslen(lpelfe->elfLogFont.lfFaceName);
fmi->family = (*env)->NewString(env,lpelfe->elfLogFont.lfFaceName, slen);
fmi->family = (*env)->NewString(env,lpelfe->elfLogFont.lfFaceName, (jsize)slen);
familyLC = (*env)->CallObjectMethod(env, fmi->family,
fmi->toLowerCaseMID, fmi->locale);
/* check if already seen this family with a different charset */
......@@ -386,10 +386,10 @@ static int CALLBACK EnumFamilyNamesW(
static BOOL RegistryToBaseTTNameA(LPSTR name) {
static const char TTSUFFIX[] = " (TrueType)";
static const char OTSUFFIX[] = " (OpenType)";
int TTSLEN = strlen(TTSUFFIX);
size_t TTSLEN = strlen(TTSUFFIX);
char *suffix;
int len = strlen(name);
size_t len = strlen(name);
if (len == 0) {
return FALSE;
}
......@@ -412,10 +412,10 @@ static BOOL RegistryToBaseTTNameA(LPSTR name) {
static BOOL RegistryToBaseTTNameW(LPWSTR name) {
static const wchar_t TTSUFFIX[] = L" (TrueType)";
static const wchar_t OTSUFFIX[] = L" (OpenType)";
int TTSLEN = wcslen(TTSUFFIX);
size_t TTSLEN = wcslen(TTSUFFIX);
wchar_t *suffix;
int len = wcslen(name);
size_t len = wcslen(name);
if (len == 0) {
return FALSE;
}
......@@ -439,7 +439,7 @@ static void registerFontA(GdiFontMapInfo *fmi, jobject fontToFileMap,
LPSTR ptr1, ptr2;
jstring fontStr;
JNIEnv *env = fmi->env;
int dslen = strlen(data);
size_t dslen = strlen(data);
jstring fileStr = JNU_NewStringPlatform(env, data);
/* TTC or ttc means it may be a collection. Need to parse out
......@@ -488,8 +488,8 @@ static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap,
wchar_t *ptr1, *ptr2;
jstring fontStr;
JNIEnv *env = fmi->env;
int dslen = wcslen(data);
jstring fileStr = (*env)->NewString(env, data, dslen);
size_t dslen = wcslen(data);
jstring fileStr = (*env)->NewString(env, data, (jsize)dslen);
/* TTC or ttc means it may be a collection. Need to parse out
* multiple font face names separated by " & "
......@@ -510,7 +510,7 @@ static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap,
while ((ptr2 = wcsstr(ptr1, L" & ")) != NULL) {
ptr1 = ptr2+3;
}
fontStr = (*env)->NewString(env, ptr1, wcslen(ptr1));
fontStr = (*env)->NewString(env, ptr1, (jsize)wcslen(ptr1));
fontStr = (*env)->CallObjectMethod(env, fontStr,
fmi->toLowerCaseMID,
fmi->locale);
......@@ -524,7 +524,7 @@ static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap,
}
}
} else {
fontStr = (*env)->NewString(env, name, wcslen(name));
fontStr = (*env)->NewString(env, name, (jsize)wcslen(name));
fontStr = (*env)->CallObjectMethod(env, fontStr,
fmi->toLowerCaseMID, fmi->locale);
(*env)->CallObjectMethod(env, fontToFileMap, fmi->putMID,
......
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
@test
@bug 5089429 6982632
@summary Checks that we don't crash if rendering operations and state
changes are performed on a graphics context from different threads.
@author Dmitri.Trembovetski@sun.com area=Graphics
@run main MTGraphicsAccessTest
*/
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
public class MTGraphicsAccessTest {
// in seconds
static final long STANDALONE_RUN_TIME = 20;
static final long JTREG_RUN_TIME = 7;
static boolean standaloneMode;
static boolean allowExceptions = true;
static long testRunTime;
volatile boolean done;
volatile int stillRunning;
volatile int numexceptions;
Graphics2D sharedGraphics;
BufferedImage sharedBI =
new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);
static final Paint colors[] = {
Color.red,
new Color(0x7f, 0xff, 0x00, 0x7f),
new GradientPaint(0, 0, Color.red,
50, 50, new Color(0x7f, 0xff, 0x00, 0x7f)),
};
static final Font fonts[] = {
new Font("Dialog", Font.PLAIN, 12),
new Font("Dialog", Font.BOLD, 16),
new Font("Dialog", Font.ITALIC, 18),
};
static final AlphaComposite comps[] = {
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f),
AlphaComposite.Src,
AlphaComposite.Xor,
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f),
null,
};
static final Stroke strokes[] = {
new BasicStroke(),
new BasicStroke(0.0f),
new BasicStroke(2.0f),
new BasicStroke(2.0f, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_BEVEL),
new BasicStroke(5.0f, BasicStroke.CAP_SQUARE,
BasicStroke.JOIN_ROUND),
new BasicStroke(0.0f, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND, 0,
new float[]{0,6,0,6}, 0),
};
static final AffineTransform transforms[] = {
new AffineTransform(),
AffineTransform.getRotateInstance(10.0),
AffineTransform.getShearInstance(10.0, 4.0),
AffineTransform.getScaleInstance(1.1, 1.2),
AffineTransform.getScaleInstance(3.0, 2.0),
};
public MTGraphicsAccessTest() {
BufferedImage bi =
new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);
sharedGraphics = (Graphics2D)bi.getGraphics();
done = false;
numexceptions = 0;
for (int i = 0; i < (standaloneMode ? stateChangers.length : 3); i++) {
(new TesterThread(stateChangers[i])).start();
}
for (int i = 0; i < (standaloneMode ? renderTests.length : 5); i++) {
(new TesterThread(renderTests[i])).start();
}
mysleep(testRunTime);
done = true;
while (stillRunning > 0) { mysleep(500); }
if (numexceptions == 0) {
System.err.println("Test passed");
} else if (!allowExceptions) {
throw new RuntimeException("Test failed with "+
numexceptions+" exceptions");
} else {
System.err.println("Test finished with "+
numexceptions+" exceptions");
}
}
private void mysleep(long time) {
try {
// add +/-5ms variance to increase randomness
Thread.sleep(time + (long)(5 - Math.random()*10));
} catch (InterruptedException e) {};
}
public static void usage(String message) {
if (message != null) {
System.err.println(message);
}
System.err.println("Usage: MTGraphicsAccessTest [-full] "+
"[-time N/forever] [-help]");
System.err.println(" -full: run full suite of tests "+
"(default: limited number of tests is run)");
System.err.println(" -time N: test duration in seconds/forever"+
" (default: "+JTREG_RUN_TIME+"s for the short suite, "+
STANDALONE_RUN_TIME+"s for the full suite)");
System.err.println(" -help: print this help page");
System.exit(1);
}
public static void main(String[] args) {
boolean testRunSet = false;
for (int i = 0; i < args.length; i++) {
if ("-full".equals(args[i])) {
standaloneMode = true;
System.err.println("Running complete list of tests");
} else if ("-noexc".equals(args[i])) {
allowExceptions = false;
} else if ("-time".equals(args[i])) {
try {
String time = args[++i];
if ("forever".equals(time)) {
testRunTime = (Long.MAX_VALUE - 20)/1000;
} else {
testRunTime = 1000*Integer.parseInt(time);
}
testRunSet = true;
} catch (NumberFormatException e) {
usage("Can't parse number of seconds: " + args[i]);
} catch (ArrayIndexOutOfBoundsException e1) {
usage("Missing the 'seconds' argument for -time parameter");
}
} else if ("-help".equals(args[i])) {
usage(null);
} else {
usage("Unknown argument:" + args[i]);
}
}
if (!testRunSet) {
testRunTime = 1000 *
(standaloneMode ? STANDALONE_RUN_TIME : JTREG_RUN_TIME);
}
System.err.println("Approximate test run time: "+
testRunTime/1000+" seconds");
new MTGraphicsAccessTest();
}
class TesterThread extends Thread {
Runnable testRunnable;
public TesterThread(Runnable testRunnable) {
stillRunning++;
this.testRunnable = testRunnable;
}
public void run() {
try {
while (!done) {
try {
testRunnable.run();
yield();
} catch (Throwable t) {
numexceptions++;
t.printStackTrace();
}
}
} finally {
stillRunning--;
}
}
}
final Runnable stateChangers[] = {
new Runnable() {
public void run() {
sharedGraphics.setClip(10, 10, 30, 30);
mysleep(10);
}
},
new Runnable() {
public void run() {
sharedGraphics.setClip(10, 10, 30, 30);
mysleep(10);
}
},
new Runnable() {
int c = 0;
public void run() {
sharedGraphics.setPaint(colors[c++ % colors.length]);
mysleep(10);
}
},
new Runnable() {
boolean AA = false;
public void run() {
if (AA) {
sharedGraphics.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
} else {
sharedGraphics.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
}
AA = !AA;
mysleep(10);
}
},
new Runnable() {
int t = 0;
public void run() {
sharedGraphics.setTransform(
transforms[t++ % transforms.length]);
mysleep(10);
}
},
new Runnable() {
int c = 0;
public void run() {
AlphaComposite comp = comps[c++ % comps.length];
if (comp == null) {
sharedGraphics.setXORMode(Color.green);
} else {
sharedGraphics.setComposite(comp);
}
mysleep(10);
}
},
new Runnable() {
int s = 0;
public void run() {
sharedGraphics.setStroke(strokes[s++ % strokes.length]);
mysleep(10);
}
},
new Runnable() {
int f = 0;
public void run() {
sharedGraphics.setFont(fonts[f++ % fonts.length]);
mysleep(10);
}
},
};
final Runnable renderTests[] = {
new Runnable() {
public void run() {
sharedGraphics.drawLine(10, 10, 30, 30);
}
},
new Runnable() {
public void run() {
sharedGraphics.drawLine(10, 10, 30, 30);
}
},
new Runnable() {
public void run() {
sharedGraphics.drawRect(10, 10, 30, 30);
}
},
new Runnable() {
public void run() {
sharedGraphics.fillRect(10, 10, 30, 30);
}
},
new Runnable() {
public void run() {
sharedGraphics.drawString("Stuff", 10, 10);
}
},
new Runnable() {
public void run() {
sharedGraphics.draw3DRect(10, 10, 30, 30, true);
}
},
new Runnable() {
public void run() {
sharedGraphics.drawImage(sharedBI, 10, 10, null);
}
},
new Runnable() {
public void run() {
sharedGraphics.fill3DRect(10, 10, 30, 30, false);
}
},
// REMIND: copyArea doesn't work when transform is set..
// new Runnable() {
// public void run() {
// sharedGraphics.copyArea(10, 10, 30, 30, 20, 20);
// }
// },
new Runnable() {
public void run() {
sharedGraphics.drawRoundRect(10, 10, 30, 30, 20, 20);
}
},
new Runnable() {
public void run() {
sharedGraphics.fillRoundRect(10, 10, 30, 30, 20, 20);
}
},
new Runnable() {
public void run() {
sharedGraphics.drawArc(10, 10, 30, 30, 0, 90);
}
},
new Runnable() {
public void run() {
sharedGraphics.fillArc(10, 10, 30, 30, 0, 90);
}
},
new Runnable() {
public void run() {
sharedGraphics.drawOval(10, 10, 30, 30);
}
},
new Runnable() {
public void run() {
sharedGraphics.fillOval(10, 10, 30, 30);
}
}
};
}
......@@ -23,7 +23,7 @@
/**
* @test
* @bug 7027667, 7023591
* @bug 7027667 7023591 7037091
*
* @summary Verifies that aa clipped rectangles are drawn, not filled.
*
......
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 7036754
*
* @summary Verifies that there are no non-finite numbers when stroking
* certain quadratic curves.
*
* @author Jim Graham
* @run main Test7036754
*/
import java.awt.*;
import java.awt.geom.*;
public class Test7036754 {
public static void main(String argv[]) {
Shape s = new QuadCurve2D.Float(839.24677f, 508.97888f,
839.2953f, 508.97122f,
839.3438f, 508.96353f);
s = new BasicStroke(10f).createStrokedShape(s);
float nsegs[] = {2, 2, 4, 6, 0};
float coords[] = new float[6];
PathIterator pi = s.getPathIterator(null);
while (!pi.isDone()) {
int type = pi.currentSegment(coords);
for (int i = 0; i < nsegs[type]; i++) {
float c = coords[i];
if (Float.isNaN(c) || Float.isInfinite(c)) {
throw new RuntimeException("bad value in stroke");
}
}
pi.next();
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册