Merge
diff --git a/src/macosx/classes/sun/font/CStrike.java b/src/macosx/classes/sun/font/CStrike.java
index 9635b85..af4f875 100644
--- a/src/macosx/classes/sun/font/CStrike.java
+++ b/src/macosx/classes/sun/font/CStrike.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, 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
@@ -31,7 +31,7 @@
import sun.awt.SunHints;
-public class CStrike extends FontStrike {
+public final class CStrike extends FontStrike {
// Creates the native strike
private static native long createNativeStrikePtr(long nativeFontPtr,
@@ -68,10 +68,10 @@
Rectangle2D.Float result,
double x, double y);
- private CFont nativeFont;
+ private final CFont nativeFont;
private AffineTransform invDevTx;
- private GlyphInfoCache glyphInfoCache;
- private GlyphAdvanceCache glyphAdvanceCache;
+ private final GlyphInfoCache glyphInfoCache;
+ private final GlyphAdvanceCache glyphAdvanceCache;
private long nativeStrikePtr;
CStrike(final CFont font, final FontStrikeDesc inDesc) {
@@ -84,11 +84,11 @@
// Normally the device transform should be the identity transform
// for screen operations. The device transform only becomes
// interesting when we are outputting between different dpi surfaces,
- // like when we are printing to postscript.
+ // like when we are printing to postscript or use retina.
if (inDesc.devTx != null && !inDesc.devTx.isIdentity()) {
try {
invDevTx = inDesc.devTx.createInverse();
- } catch (NoninvertibleTransformException e) {
+ } catch (NoninvertibleTransformException ignored) {
// ignored, since device transforms should not be that
// complicated, and if they are - there is nothing we can do,
// so we won't worry about it.
@@ -134,15 +134,13 @@
nativeStrikePtr = 0;
}
- // the fractional metrics default on our platform is OFF
- private boolean useFractionalMetrics() {
- return desc.fmHint == SunHints.INTVAL_FRACTIONALMETRICS_ON;
- }
+ @Override
public int getNumGlyphs() {
return nativeFont.getNumGlyphs();
}
+ @Override
StrikeMetrics getFontMetrics() {
if (strikeMetrics == null) {
StrikeMetrics metrics = getFontMetrics(getNativeStrikePtr());
@@ -155,74 +153,24 @@
return strikeMetrics;
}
- float getGlyphAdvance(int glyphCode) {
- return getScaledAdvanceForAdvance(getCachedNativeGlyphAdvance(glyphCode));
+ @Override
+ float getGlyphAdvance(final int glyphCode) {
+ return getCachedNativeGlyphAdvance(glyphCode);
}
- float getCodePointAdvance(int cp) {
- float advance = getCachedNativeGlyphAdvance(nativeFont.getMapper().charToGlyph(cp));
-
- double glyphScaleX = desc.glyphTx.getScaleX();
- double devScaleX = desc.devTx.getScaleX();
-
- if (devScaleX == 0) {
- glyphScaleX = Math.sqrt(desc.glyphTx.getDeterminant());
- devScaleX = Math.sqrt(desc.devTx.getDeterminant());
- }
-
- if (devScaleX == 0) {
- devScaleX = Double.NaN; // this an undefined graphics state
- }
- advance = (float) (advance * glyphScaleX / devScaleX);
- return useFractionalMetrics() ? advance : Math.round(advance);
+ @Override
+ float getCodePointAdvance(final int cp) {
+ return getGlyphAdvance(nativeFont.getMapper().charToGlyph(cp));
}
- // calculate an advance, and round if not using fractional metrics
- private float getScaledAdvanceForAdvance(float advance) {
- if (invDevTx != null) {
- advance *= invDevTx.getScaleX();
- }
- advance *= desc.glyphTx.getScaleX();
- return useFractionalMetrics() ? advance : Math.round(advance);
+ @Override
+ Point2D.Float getCharMetrics(final char ch) {
+ return getGlyphMetrics(nativeFont.getMapper().charToGlyph(ch));
}
- Point2D.Float getCharMetrics(char ch) {
- return getScaledPointForAdvance(getCachedNativeGlyphAdvance(nativeFont.getMapper().charToGlyph(ch)));
- }
-
- Point2D.Float getGlyphMetrics(int glyphCode) {
- return getScaledPointForAdvance(getCachedNativeGlyphAdvance(glyphCode));
- }
-
- // calculate an advance point, and round if not using fractional metrics
- private Point2D.Float getScaledPointForAdvance(float advance) {
- Point2D.Float pt = new Point2D.Float(advance, 0);
-
- if (!desc.glyphTx.isIdentity()) {
- return scalePoint(pt);
- }
-
- if (!useFractionalMetrics()) {
- pt.x = Math.round(pt.x);
- }
- return pt;
- }
-
- private Point2D.Float scalePoint(Point2D.Float pt) {
- if (invDevTx != null) {
- // transform the point out of the device space first
- invDevTx.transform(pt, pt);
- }
- desc.glyphTx.transform(pt, pt);
- pt.x -= desc.glyphTx.getTranslateX();
- pt.y -= desc.glyphTx.getTranslateY();
-
- if (!useFractionalMetrics()) {
- pt.x = Math.round(pt.x);
- pt.y = Math.round(pt.y);
- }
-
- return pt;
+ @Override
+ Point2D.Float getGlyphMetrics(final int glyphCode) {
+ return new Point2D.Float(getGlyphAdvance(glyphCode), 0.0f);
}
Rectangle2D.Float getGlyphOutlineBounds(int glyphCode) {
@@ -414,9 +362,7 @@
private SparseBitShiftingTwoLayerArray secondLayerCache;
private HashMap<Integer, Long> generalCache;
- public GlyphInfoCache(final Font2D nativeFont,
- final FontStrikeDesc desc)
- {
+ GlyphInfoCache(final Font2D nativeFont, final FontStrikeDesc desc) {
super(nativeFont, desc);
firstLayerCache = new long[FIRST_LAYER_SIZE];
}
@@ -527,7 +473,7 @@
final int shift;
final int secondLayerLength;
- public SparseBitShiftingTwoLayerArray(final int size, final int shift) {
+ SparseBitShiftingTwoLayerArray(final int size, final int shift) {
this.shift = shift;
this.cache = new long[1 << shift][];
this.secondLayerLength = size >> shift;
@@ -559,6 +505,12 @@
private SparseBitShiftingTwoLayerArray secondLayerCache;
private HashMap<Integer, Float> generalCache;
+ // Empty non private constructor was added because access to this
+ // class shouldn't be emulated by a synthetic accessor method.
+ GlyphAdvanceCache() {
+ super();
+ }
+
public synchronized float get(final int index) {
if (index < 0) {
if (-index < SECOND_LAYER_SIZE) {
@@ -609,9 +561,7 @@
final int shift;
final int secondLayerLength;
- public SparseBitShiftingTwoLayerArray(final int size,
- final int shift)
- {
+ SparseBitShiftingTwoLayerArray(final int size, final int shift) {
this.shift = shift;
this.cache = new float[1 << shift][];
this.secondLayerLength = size >> shift;
diff --git a/src/macosx/native/sun/font/AWTStrike.h b/src/macosx/native/sun/font/AWTStrike.h
index 41bbe4d..05ef198 100644
--- a/src/macosx/native/sun/font/AWTStrike.h
+++ b/src/macosx/native/sun/font/AWTStrike.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, 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
@@ -31,11 +31,12 @@
@interface AWTStrike : NSObject {
@public
AWTFont * fAWTFont;
- CGFloat fSize;
+ CGFloat fSize;
JRSFontRenderingStyle fStyle;
- jint fAAStyle;
+ jint fAAStyle;
CGAffineTransform fTx;
+ CGAffineTransform fDevTx;
CGAffineTransform fAltTx; // alternate strike tx used for Sun2D
CGAffineTransform fFontTx;
}
diff --git a/src/macosx/native/sun/font/AWTStrike.m b/src/macosx/native/sun/font/AWTStrike.m
index 7f04b53..6e4b429 100644
--- a/src/macosx/native/sun/font/AWTStrike.m
+++ b/src/macosx/native/sun/font/AWTStrike.m
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, 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
@@ -65,6 +65,7 @@
invDevTx.b *= -1;
invDevTx.c *= -1;
fFontTx = CGAffineTransformConcat(CGAffineTransformConcat(tx, invDevTx), sInverseTX);
+ fDevTx = CGAffineTransformInvert(invDevTx);
// the "font size" is the square root of the determinant of the matrix
fSize = sqrt(abs(fFontTx.a * fFontTx.d - fFontTx.b * fFontTx.c));
@@ -148,7 +149,8 @@
{
CGSize advance;
JNF_COCOA_ENTER(env);
- AWTFont *awtFont = ((AWTStrike *)jlong_to_ptr(awtStrikePtr))->fAWTFont;
+ AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
+ AWTFont *awtFont = awtStrike->fAWTFont;
// negative glyph codes are really unicodes, which were placed there by the mapper
// to indicate we should use CoreText to substitute the character
@@ -156,6 +158,10 @@
const CTFontRef fallback = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtFont, glyphCode, &glyph);
CTFontGetAdvancesForGlyphs(fallback, kCTFontDefaultOrientation, &glyph, &advance, 1);
CFRelease(fallback);
+ advance = CGSizeApplyAffineTransform(advance, awtStrike->fFontTx);
+ if (!JRSFontStyleUsesFractionalMetrics(awtStrike->fStyle)) {
+ advance.width = round(advance.width);
+ }
JNF_COCOA_EXIT(env);
return advance.width;
diff --git a/src/macosx/native/sun/font/CGGlyphImages.m b/src/macosx/native/sun/font/CGGlyphImages.m
index 508c127..1901c1f 100644
--- a/src/macosx/native/sun/font/CGGlyphImages.m
+++ b/src/macosx/native/sun/font/CGGlyphImages.m
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, 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
@@ -455,6 +455,7 @@
#define CGGI_GLYPH_BBOX_PADDING 2.0f
static inline GlyphInfo *
CGGI_CreateNewGlyphInfoFrom(CGSize advance, CGRect bbox,
+ const AWTStrike *strike,
const CGGI_RenderingMode *mode)
{
size_t pixelSize = mode->glyphDescriptor->pixelSize;
@@ -477,6 +478,12 @@
width = 1;
height = 1;
}
+ advance = CGSizeApplyAffineTransform(advance, strike->fFontTx);
+ if (!JRSFontStyleUsesFractionalMetrics(strike->fStyle)) {
+ advance.width = round(advance.width);
+ advance.height = round(advance.height);
+ }
+ advance = CGSizeApplyAffineTransform(advance, strike->fDevTx);
#ifdef USE_IMAGE_ALIGNED_MEMORY
// create separate memory
@@ -564,10 +571,10 @@
JRSFontGetBoundingBoxesForGlyphsAndStyle(fallback, &tx, style, &glyph, 1, &bbox);
CGSize advance;
- JRSFontGetAdvancesForGlyphsAndStyle(fallback, &tx, strike->fStyle, &glyph, 1, &advance);
+ CTFontGetAdvancesForGlyphs(fallback, kCTFontDefaultOrientation, &glyph, &advance, 1);
// create the Sun2D GlyphInfo we are going to strike into
- GlyphInfo *info = CGGI_CreateNewGlyphInfoFrom(advance, bbox, mode);
+ GlyphInfo *info = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, mode);
// fix the context size, just in case the substituted character is unexpectedly large
CGGI_SizeCanvas(canvas, info->width, info->height, mode->cgFontMode);
@@ -715,7 +722,7 @@
JRSFontRenderingStyle bboxCGMode = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);
JRSFontGetBoundingBoxesForGlyphsAndStyle((CTFontRef)font->fFont, &tx, bboxCGMode, glyphs, len, bboxes);
- JRSFontGetAdvancesForGlyphsAndStyle((CTFontRef)font->fFont, &tx, strike->fStyle, glyphs, len, advances);
+ CTFontGetAdvancesForGlyphs((CTFontRef)font->fFont, kCTFontDefaultOrientation, glyphs, advances, len);
size_t maxWidth = 1;
size_t maxHeight = 1;
@@ -732,7 +739,7 @@
CGSize advance = advances[i];
CGRect bbox = bboxes[i];
- GlyphInfo *glyphInfo = CGGI_CreateNewGlyphInfoFrom(advance, bbox, mode);
+ GlyphInfo *glyphInfo = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, mode);
if (maxWidth < glyphInfo->width) maxWidth = glyphInfo->width;
if (maxHeight < glyphInfo->height) maxHeight = glyphInfo->height;
diff --git a/src/share/classes/sun/font/TrueTypeFont.java b/src/share/classes/sun/font/TrueTypeFont.java
index 5a3180e..e5b6ffd 100644
--- a/src/share/classes/sun/font/TrueTypeFont.java
+++ b/src/share/classes/sun/font/TrueTypeFont.java
@@ -547,6 +547,17 @@
throw new FontFormatException("bad table, tag="+table.tag);
}
}
+
+ if (getDirectoryEntry(headTag) == null) {
+ throw new FontFormatException("missing head table");
+ }
+ if (getDirectoryEntry(maxpTag) == null) {
+ throw new FontFormatException("missing maxp table");
+ }
+ if (getDirectoryEntry(hmtxTag) != null
+ && getDirectoryEntry(hheaTag) == null) {
+ throw new FontFormatException("missing hhea table");
+ }
initNames();
} catch (Exception e) {
if (FontUtilities.isLogging()) {
diff --git a/src/share/classes/sun/print/PSPrinterJob.java b/src/share/classes/sun/print/PSPrinterJob.java
index 5344ba8..c4bcc23 100644
--- a/src/share/classes/sun/print/PSPrinterJob.java
+++ b/src/share/classes/sun/print/PSPrinterJob.java
@@ -59,6 +59,8 @@
import javax.print.StreamPrintService;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.PrintServiceAttributeSet;
+import javax.print.attribute.standard.PrinterName;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Destination;
@@ -766,8 +768,9 @@
}
}
if (mDestType == RasterPrinterJob.PRINTER) {
- if (getPrintService() != null) {
- mDestination = getPrintService().getName();
+ PrintService pServ = getPrintService();
+ if (pServ != null) {
+ mDestination = pServ.getName();
}
PrinterSpooler spooler = new PrinterSpooler();
java.security.AccessController.doPrivileged(spooler);
diff --git a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
index 7411c34..e0716b1 100644
--- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
+++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
@@ -106,7 +106,7 @@
/******************** StreamBuffer definition ************************/
typedef struct streamBufferStruct {
- jobject stream; // ImageInputStream or ImageOutputStream
+ jweak ioRef; // weak reference to a provider of I/O routines
jbyteArray hstreamBuffer; // Handle to a Java buffer for the stream
JOCTET *buf; // Pinned buffer pointer */
size_t bufferOffset; // holds offset between unpin and the next pin
@@ -125,6 +125,15 @@
*/
#define STREAMBUF_SIZE 4096
+#define GET_IO_REF(io_name) \
+ do { \
+ if ((*env)->IsSameObject(env, sb->ioRef, NULL) || \
+ ((io_name) = (*env)->NewLocalRef(env, sb->ioRef)) == NULL) \
+ { \
+ cinfo->err->error_exit((j_common_ptr) cinfo); \
+ } \
+ } while (0) \
+
/*
* Used to signal that no data need be restored from an unpin to a pin.
* I.e. the buffer is empty.
@@ -159,7 +168,7 @@
}
- sb->stream = NULL;
+ sb->ioRef = NULL;
sb->buf = NULL;
@@ -191,9 +200,9 @@
* All other state is reset.
*/
static void resetStreamBuffer(JNIEnv *env, streamBufferPtr sb) {
- if (sb->stream != NULL) {
- (*env)->DeleteGlobalRef(env, sb->stream);
- sb->stream = NULL;
+ if (sb->ioRef != NULL) {
+ (*env)->DeleteWeakGlobalRef(env, sb->ioRef);
+ sb->ioRef = NULL;
}
unpinStreamBuffer(env, sb, NULL);
sb->bufferOffset = NO_DATA;
@@ -571,7 +580,7 @@
static void imageio_set_stream(JNIEnv *env,
j_common_ptr cinfo,
imageIODataPtr data,
- jobject stream){
+ jobject io){
streamBufferPtr sb;
sun_jpeg_error_ptr jerr;
@@ -579,13 +588,13 @@
resetStreamBuffer(env, sb); // Removes any old stream
- /* Now we need a new global reference for the stream */
- if (stream != NULL) { // Fix for 4411955
- sb->stream = (*env)->NewGlobalRef(env, stream);
- if (sb->stream == NULL) {
+ /* Now we need a new weak global reference for the I/O provider */
+ if (io != NULL) { // Fix for 4411955
+ sb->ioRef = (*env)->NewWeakGlobalRef(env, io);
+ if (sb->ioRef == NULL) {
JNU_ThrowByName(env,
"java/lang/OutOfMemoryError",
- "Setting Stream");
+ "Setting I/O provider");
return;
}
}
@@ -895,6 +904,7 @@
streamBufferPtr sb = &data->streamBuf;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
int ret;
+ jobject input = NULL;
/* This is where input suspends */
if (sb->suspendable) {
@@ -920,9 +930,11 @@
* Now fill a complete buffer, or as much of one as the stream
* will give us if we are near the end.
*/
+ GET_IO_REF(input);
+
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallIntMethod(env,
- sb->stream,
+ input,
JPEGImageReader_readInputDataID,
sb->hstreamBuffer, 0,
sb->bufferLength);
@@ -982,6 +994,7 @@
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jint ret;
size_t offset, buflen;
+ jobject input = NULL;
/*
* The original (jpegdecoder.c) had code here that called
@@ -1003,6 +1016,9 @@
if (src->next_input_byte > sb->buf) {
memcpy(sb->buf, src->next_input_byte, offset);
}
+
+ GET_IO_REF(input);
+
RELEASE_ARRAYS(env, data, src->next_input_byte);
buflen = sb->bufferLength - offset;
if (buflen <= 0) {
@@ -1012,7 +1028,7 @@
return;
}
- ret = (*env)->CallIntMethod(env, sb->stream,
+ ret = (*env)->CallIntMethod(env, input,
JPEGImageReader_readInputDataID,
sb->hstreamBuffer,
offset, buflen);
@@ -1075,6 +1091,7 @@
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jlong ret;
jobject reader;
+ jobject input = NULL;
if (num_bytes < 0) {
return;
@@ -1104,9 +1121,11 @@
return;
}
+ GET_IO_REF(input);
+
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallLongMethod(env,
- sb->stream,
+ input,
JPEGImageReader_skipInputBytesID,
(jlong) num_bytes);
if ((*env)->ExceptionOccurred(env)
@@ -2285,11 +2304,14 @@
imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
streamBufferPtr sb = &data->streamBuf;
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+ jobject output = NULL;
+
+ GET_IO_REF(output);
RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
(*env)->CallVoidMethod(env,
- sb->stream,
+ output,
JPEGImageWriter_writeOutputDataID,
sb->hstreamBuffer,
0,
@@ -2322,11 +2344,16 @@
/* find out how much needs to be written */
/* this conversion from size_t to jint is safe, because the lenght of the buffer is limited by jint */
jint datacount = (jint)(sb->bufferLength - dest->free_in_buffer);
+
if (datacount != 0) {
+ jobject output = NULL;
+
+ GET_IO_REF(output);
+
RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
(*env)->CallVoidMethod(env,
- sb->stream,
+ output,
JPEGImageWriter_writeOutputDataID,
sb->hstreamBuffer,
0,
diff --git a/src/share/native/sun/awt/medialib/awt_ImagingLib.c b/src/share/native/sun/awt/medialib/awt_ImagingLib.c
index 2576421..003ad8d 100644
--- a/src/share/native/sun/awt/medialib/awt_ImagingLib.c
+++ b/src/share/native/sun/awt/medialib/awt_ImagingLib.c
@@ -2606,38 +2606,37 @@
#define ERR_BAD_IMAGE_LAYOUT (-2)
-#define CHECK_DST_ARRAY(start_offset, elements_per_pixel) \
- do { \
- int offset = (start_offset); \
- int lastScanOffset; \
- \
- if (!SAFE_TO_MULT(rasterP->scanlineStride, \
- (rasterP->height - 1))) \
- { \
- return ERR_BAD_IMAGE_LAYOUT; \
- } \
- lastScanOffset = rasterP->scanlineStride * \
- (rasterP->height - 1); \
- \
- if (!SAFE_TO_ADD(offset, lastScanOffset)) { \
- return ERR_BAD_IMAGE_LAYOUT; \
- } \
- lastScanOffset += offset; \
- \
- if (!SAFE_TO_MULT((elements_per_pixel), rasterP->width)) { \
- return ERR_BAD_IMAGE_LAYOUT; \
- } \
- offset = (elements_per_pixel) * rasterP->width; \
- \
- if (!SAFE_TO_ADD(offset, lastScanOffset)) { \
- return ERR_BAD_IMAGE_LAYOUT; \
- } \
- lastScanOffset += offset; \
- \
- if (dataArrayLength < lastScanOffset) { \
- return ERR_BAD_IMAGE_LAYOUT; \
- } \
- } while(0); \
+#define CHECK_DST_ARRAY(start_offset, elements_per_scan, elements_per_pixel) \
+ do { \
+ int offset = (start_offset); \
+ int lastScanOffset; \
+ \
+ if (!SAFE_TO_MULT((elements_per_scan), \
+ (rasterP->height - 1))) \
+ { \
+ return ERR_BAD_IMAGE_LAYOUT; \
+ } \
+ lastScanOffset = (elements_per_scan) * (rasterP->height - 1); \
+ \
+ if (!SAFE_TO_ADD(offset, lastScanOffset)) { \
+ return ERR_BAD_IMAGE_LAYOUT; \
+ } \
+ lastScanOffset += offset; \
+ \
+ if (!SAFE_TO_MULT((elements_per_pixel), rasterP->width)) { \
+ return ERR_BAD_IMAGE_LAYOUT; \
+ } \
+ offset = (elements_per_pixel) * rasterP->width; \
+ \
+ if (!SAFE_TO_ADD(offset, lastScanOffset)) { \
+ return ERR_BAD_IMAGE_LAYOUT; \
+ } \
+ lastScanOffset += offset; \
+ \
+ if (dataArrayLength < lastScanOffset) { \
+ return ERR_BAD_IMAGE_LAYOUT; \
+ } \
+ } while(0); \
static int
storeImageArray(JNIEnv *env, BufImageS_t *srcP, BufImageS_t *dstP,
@@ -2665,39 +2664,33 @@
if (hintP->packing == BYTE_INTERLEAVED) {
/* Write it back to the destination */
- CHECK_DST_ARRAY(hintP->channelOffset, hintP->numChans);
+ if (rasterP->dataType != BYTE_DATA_TYPE) {
+ /* We are working with a raster which was marked
+ as a byte interleaved due to performance reasons.
+ So, we have to convert the length of the data
+ array to bytes as well.
+ */
+ if (!SAFE_TO_MULT(rasterP->dataSize, dataArrayLength)) {
+ return ERR_BAD_IMAGE_LAYOUT;
+ }
+ dataArrayLength *= rasterP->dataSize;
+ }
+
+ CHECK_DST_ARRAY(hintP->dataOffset, hintP->sStride, hintP->numChans);
cmDataP = (unsigned char *) mlib_ImageGetData(mlibImP);
mStride = mlib_ImageGetStride(mlibImP);
dataP = (unsigned char *)(*env)->GetPrimitiveArrayCritical(env,
rasterP->jdata, NULL);
if (dataP == NULL) return 0;
- cDataP = dataP + hintP->channelOffset;
+ cDataP = dataP + hintP->dataOffset;
for (y=0; y < rasterP->height;
- y++, cmDataP += mStride, cDataP += rasterP->scanlineStride)
+ y++, cmDataP += mStride, cDataP += hintP->sStride)
{
memcpy(cDataP, cmDataP, rasterP->width*hintP->numChans);
}
(*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, dataP,
JNI_ABORT);
}
- else if (hintP->packing == SHORT_INTERLEAVED) {
- /* Write it back to the destination */
- unsigned short *sdataP, *sDataP;
- unsigned short *smDataP = (unsigned short *)mlib_ImageGetData(mlibImP);
- CHECK_DST_ARRAY(hintP->channelOffset, hintP->numChans);
- mStride = mlib_ImageGetStride(mlibImP);
- sdataP = (unsigned short *)(*env)->GetPrimitiveArrayCritical(env,
- rasterP->jdata, NULL);
- if (sdataP == NULL) return -1;
- sDataP = sdataP + hintP->channelOffset;
- for (y=0; y < rasterP->height;
- y++, smDataP += mStride, sDataP += rasterP->scanlineStride)
- {
- memcpy(sDataP, smDataP, rasterP->width*hintP->numChans);
- }
- (*env)->ReleasePrimitiveArrayCritical(env, rasterP->jdata, sdataP,
- JNI_ABORT);
- }
else if (dstP->cmodel.cmType == DIRECT_CM_TYPE) {
/* Just need to move bits */
if (mlibImP->type == MLIB_BYTE) {
@@ -3499,7 +3492,7 @@
}
dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
- CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+ CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);
outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
if (outDataP == NULL) {
@@ -3575,7 +3568,7 @@
}
dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
- CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+ CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);
outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
if (outDataP == NULL) {
@@ -3651,7 +3644,7 @@
}
dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
- CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+ CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);
outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
if (outDataP == NULL) {
@@ -3730,7 +3723,7 @@
}
dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
- CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+ CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);
outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
if (outDataP == NULL) {
@@ -3827,7 +3820,7 @@
return -1;
}
dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
- CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+ CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);
outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
if (outDataP == NULL) {
@@ -3925,7 +3918,7 @@
}
dataArrayLength = (*env)->GetArrayLength(env, jOutDataP);
- CHECK_DST_ARRAY(rasterP->chanOffsets[0], 1);
+ CHECK_DST_ARRAY(rasterP->chanOffsets[0], rasterP->scanlineStride, 1);
outDataP = (*env)->GetPrimitiveArrayCritical(env, jOutDataP, 0);
if (outDataP == NULL) {
diff --git a/src/share/native/sun/font/layout/CanonShaping.cpp b/src/share/native/sun/font/layout/CanonShaping.cpp
index 86f2ebc..be011b1 100644
--- a/src/share/native/sun/font/layout/CanonShaping.cpp
+++ b/src/share/native/sun/font/layout/CanonShaping.cpp
@@ -66,6 +66,16 @@
le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
le_int32 i;
+ if (combiningClasses == NULL || indices == NULL) {
+ if (combiningClasses != NULL) {
+ LE_DELETE_ARRAY(combiningClasses);
+ }
+ if (indices != NULL) {
+ LE_DELETE_ARRAY(indices);
+ }
+ return;
+ }
+
for (i = 0; i < charCount; i += 1) {
combiningClasses[i] = classTable->getGlyphClass(classTable, (LEGlyphID) inChars[i], success);
indices[i] = i;
diff --git a/src/solaris/classes/sun/print/IPPPrintService.java b/src/solaris/classes/sun/print/IPPPrintService.java
index dea6237..da796b9 100644
--- a/src/solaris/classes/sun/print/IPPPrintService.java
+++ b/src/solaris/classes/sun/print/IPPPrintService.java
@@ -1099,6 +1099,15 @@
if (category == PrinterName.class) {
return (T)(new PrinterName(printer, null));
+ } else if (category == PrinterInfo.class) {
+ PrinterInfo pInfo = new PrinterInfo(printer, null);
+ AttributeClass ac = (getAttMap != null) ?
+ (AttributeClass)getAttMap.get(pInfo.getName())
+ : null;
+ if (ac != null) {
+ return (T)(new PrinterInfo(ac.getStringValue(), null));
+ }
+ return (T)pInfo;
} else if (category == QueuedJobCount.class) {
QueuedJobCount qjc = new QueuedJobCount(0);
AttributeClass ac = (getAttMap != null) ?
@@ -1566,7 +1575,24 @@
}
}
+ String getDest() {
+ return printer;
+ }
+
public String getName() {
+ /*
+ * Mac is using printer-info IPP attribute for its human-readable printer
+ * name and is also the identifier used in NSPrintInfo:setPrinter.
+ */
+ if (UnixPrintServiceLookup.isMac()) {
+ PrintServiceAttributeSet psaSet = this.getAttributes();
+ if (psaSet != null) {
+ PrinterInfo pName = (PrinterInfo)psaSet.get(PrinterInfo.class);
+ if (pName != null) {
+ return pName.toString();
+ }
+ }
+ }
return printer;
}
diff --git a/src/solaris/classes/sun/print/UnixPrintJob.java b/src/solaris/classes/sun/print/UnixPrintJob.java
index 8c797ce..b394884 100644
--- a/src/solaris/classes/sun/print/UnixPrintJob.java
+++ b/src/solaris/classes/sun/print/UnixPrintJob.java
@@ -65,6 +65,7 @@
import javax.print.attribute.PrintJobAttributeSet;
import javax.print.attribute.PrintRequestAttribute;
import javax.print.attribute.PrintRequestAttributeSet;
+import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.DocumentName;
@@ -76,6 +77,7 @@
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.OrientationRequested;
+import javax.print.attribute.standard.PrinterName;
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.NumberUp;
import javax.print.attribute.standard.Sides;
@@ -120,6 +122,9 @@
UnixPrintJob(PrintService service) {
this.service = service;
mDestination = service.getName();
+ if (UnixPrintServiceLookup.isMac()) {
+ mDestination = ((IPPPrintService)service).getDest();
+ }
mDestType = UnixPrintJob.DESTPRINTER;
}
diff --git a/src/solaris/native/sun/awt/awt_GraphicsEnv.c b/src/solaris/native/sun/awt/awt_GraphicsEnv.c
index cb0b727..4b6e2c6 100644
--- a/src/solaris/native/sun/awt/awt_GraphicsEnv.c
+++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.c
@@ -926,6 +926,11 @@
*shmExt = canUseShmExt = CANT_USE_MITSHM;
*shmPixmaps = canUseShmExtPixmaps = CANT_USE_MITSHM;
+ if (awt_display == (Display *)NULL) {
+ AWT_NOFLUSH_UNLOCK();
+ return;
+ }
+
/**
* XShmQueryExtension returns False in remote server case.
* Unfortunately it also returns True in ssh case, so
diff --git a/src/solaris/native/sun/java2d/x11/XRBackendNative.c b/src/solaris/native/sun/java2d/x11/XRBackendNative.c
index 3b38bba..241c96f 100644
--- a/src/solaris/native/sun/java2d/x11/XRBackendNative.c
+++ b/src/solaris/native/sun/java2d/x11/XRBackendNative.c
@@ -112,6 +112,25 @@
#define PKGINFO_LINE_LEN_MAX 256
#define PKGINFO_LINE_CNT_MAX 50
+/*
+ * X protocol uses (u_int16)length to specify the length in 4 bytes quantities
+ * of the whole request. Both XRenderFillRectangles() and XFillRectangles()
+ * have provisions to fragment into several requests if the number of rectangles
+ * plus the current x request does not fit into 65535*4 bytes. While
+ * XRenderCreateLinearGradient() and XRenderCreateRadialGradient() have
+ * provisions to gracefully degrade if the resulting request would exceed
+ * 65535*4 bytes.
+ *
+ * Below, we define a cap of 65535*4 bytes for the maximum X request payload
+ * allowed for Non-(XRenderFillRectangles() or XFillRectangles()) API calls,
+ * just to be conservative. This is offset by the size of our maximum x*Req
+ * type in this compilation unit, which is xRenderCreateRadiaGradientReq.
+ *
+ * Note that sizeof(xRenderCreateRadiaGradientReq) = 36
+ */
+#define MAX_PAYLOAD (262140u - 36u)
+#define MAXUINT (0xffffffffu)
+
static jboolean IsXRenderAvailable(jboolean verbose) {
void *xrenderlib;
@@ -267,13 +286,19 @@
char *maskData;
XImage* defaultImg;
jfieldID maskImgID;
- jlong fmt8 =
- ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardA8));
- jlong fmt32 =
- ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardARGB32));
+ jlong fmt8;
+ jlong fmt32;
+
jfieldID a8ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_A8", "J");
jfieldID argb32ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_ARGB32", "J");
+ if (awt_display == (Display *)NULL) {
+ return;
+ }
+
+ fmt8 = ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardA8));
+ fmt32 = ptr_to_jlong(XRenderFindStandardFormat(awt_display, PictStandardARGB32));
+
(*env)->SetStaticLongField(env, cls, a8ID, fmt8);
(*env)->SetStaticLongField(env, cls, argb32ID, fmt32);
@@ -404,6 +429,10 @@
if (rectCnt <= 256) {
xRects = &sRects[0];
} else {
+ if (MAXUINT / sizeof(XRectangle) < (unsigned)rectCnt) {
+ /* rectCnt too big, integer overflow */
+ return;
+ }
xRects = (XRectangle *) malloc(sizeof(XRectangle) * rectCnt);
if (xRects == NULL) {
return;
@@ -460,6 +489,12 @@
XFixed *stops;
XLinearGradient grad;
+ if (MAX_PAYLOAD / (sizeof(XRenderColor) + sizeof(XFixed))
+ < (unsigned)numStops) {
+ /* numStops too big, payload overflow */
+ return -1;
+ }
+
if ((pixels = (jshort *)
(*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) {
return -1;
@@ -480,6 +515,18 @@
colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor));
stops = (XFixed *) malloc(numStops * sizeof(XFixed));
+ if (colors == NULL || stops == NULL) {
+ if (colors != NULL) {
+ free(colors);
+ }
+ if (stops != NULL) {
+ free(stops);
+ }
+ (*env)->ReleasePrimitiveArrayCritical(env, pixelsArray, pixels, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, fractions, JNI_ABORT);
+ return -1;
+ }
+
for (i=0; i < numStops; i++) {
stops[i] = XDoubleToFixed(fractions[i]);
colors[i].alpha = pixels[i*4 + 0];
@@ -527,6 +574,11 @@
XFixed *stops;
XRadialGradient grad;
+ if (MAX_PAYLOAD / (sizeof(XRenderColor) + sizeof(XFixed))
+ < (unsigned)numStops) {
+ /* numStops too big, payload overflow */
+ return -1;
+ }
if ((pixels =
(jshort *)(*env)->GetPrimitiveArrayCritical(env, pixelsArray, NULL)) == NULL) {
@@ -550,6 +602,18 @@
colors = (XRenderColor *) malloc(numStops * sizeof(XRenderColor));
stops = (XFixed *) malloc(numStops * sizeof(XFixed));
+ if (colors == NULL || stops == NULL) {
+ if (colors != NULL) {
+ free(colors);
+ }
+ if (stops != NULL) {
+ free(stops);
+ }
+ (*env)->ReleasePrimitiveArrayCritical(env, pixelsArray, pixels, JNI_ABORT);
+ (*env)->ReleasePrimitiveArrayCritical(env, fractionsArray, fractions, JNI_ABORT);
+ return -1;
+ }
+
for (i=0; i < numStops; i++) {
stops[i] = XDoubleToFixed(fractions[i]);
colors[i].alpha = pixels[i*4 + 0];
@@ -708,6 +772,12 @@
unsigned char *pixelData;
int i;
+ if (MAX_PAYLOAD / (sizeof(XGlyphInfo) + sizeof(Glyph))
+ < (unsigned)glyphCnt) {
+ /* glyphCnt too big, payload overflow */
+ return;
+ }
+
XGlyphInfo *xginfo = (XGlyphInfo *) malloc(sizeof(XGlyphInfo) * glyphCnt);
Glyph *gid = (Glyph *) malloc(sizeof(Glyph) * glyphCnt);
@@ -770,6 +840,11 @@
Java_sun_java2d_xr_XRBackendNative_XRFreeGlyphsNative
(JNIEnv *env, jclass cls, jint glyphSet, jintArray gidArray, jint glyphCnt) {
+ if (MAX_PAYLOAD / sizeof(Glyph) < (unsigned)glyphCnt) {
+ /* glyphCnt too big, payload overflow */
+ return;
+ }
+
/* The glyph ids are 32 bit but may be stored in a 64 bit long on
* a 64 bit architecture. So optimise the 32 bit case to avoid
* extra stack or heap allocations by directly referencing the
@@ -840,6 +915,15 @@
unsigned int sids[256];
int charCnt = 0;
+ if ((MAX_PAYLOAD / sizeof(XGlyphElt32) < (unsigned)eltCnt)
+ || (MAX_PAYLOAD / sizeof(unsigned int) < (unsigned)glyphCnt)
+ || ((MAX_PAYLOAD - sizeof(XGlyphElt32)*(unsigned)eltCnt) /
+ sizeof(unsigned int) < (unsigned)glyphCnt))
+ {
+ /* (eltCnt, glyphCnt) too big, payload overflow */
+ return;
+ }
+
if (eltCnt <= 24) {
xelts = &selts[0];
}else {
@@ -938,6 +1022,11 @@
if (rectCnt <= 256) {
xRects = &sRects[0];
} else {
+ if (MAXUINT / sizeof(XRectangle) < (unsigned)rectCnt) {
+ /* rectCnt too big, integer overflow */
+ return;
+ }
+
xRects = (XRectangle *) malloc(sizeof(XRectangle) * rectCnt);
if (xRects == NULL) {
return;
diff --git a/src/windows/classes/sun/print/Win32PrintService.java b/src/windows/classes/sun/print/Win32PrintService.java
index 829eaaa..c42de1a 100644
--- a/src/windows/classes/sun/print/Win32PrintService.java
+++ b/src/windows/classes/sun/print/Win32PrintService.java
@@ -445,7 +445,7 @@
initMedia();
- if ((mediaSizeNames == null) && (mediaSizeNames.length == 0)) {
+ if ((mediaSizeNames == null) || (mediaSizeNames.length == 0)) {
return null;
}
diff --git a/test/java/awt/Graphics2D/DrawString/DrawRotatedString.java b/test/java/awt/Graphics2D/DrawString/DrawRotatedString.java
new file mode 100644
index 0000000..8564bb5
--- /dev/null
+++ b/test/java/awt/Graphics2D/DrawString/DrawRotatedString.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+/**
+ * @test
+ * @bug 7190349
+ * @summary Verifies that we get correct direction, when draw rotated string.
+ * @author Sergey Bylokhov
+ * @run main/othervm DrawRotatedString
+ */
+public final class DrawRotatedString {
+
+ private static final int SIZE = 500;
+
+ public static void main(final String[] args) throws IOException {
+ BufferedImage bi = createBufferedImage(true);
+ verify(bi);
+ bi = createBufferedImage(false);
+ verify(bi);
+ System.out.println("Passed");
+ }
+
+ private static void verify(BufferedImage bi) throws IOException {
+ for (int i = 0; i < SIZE; ++i) {
+ for (int j = 0; j < 99; ++j) {
+ //Text should not appear before 100
+ if (bi.getRGB(i, j) != Color.RED.getRGB()) {
+ ImageIO.write(bi, "png", new File("image.png"));
+ throw new RuntimeException("Failed: wrong text location");
+ }
+ }
+ }
+ }
+
+ private static BufferedImage createBufferedImage(final boolean aa) {
+ final BufferedImage bi = new BufferedImage(SIZE, SIZE,
+ BufferedImage.TYPE_INT_RGB);
+ final Graphics2D bg = bi.createGraphics();
+ bg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ aa ? RenderingHints.VALUE_ANTIALIAS_ON
+ : RenderingHints.VALUE_ANTIALIAS_OFF);
+ bg.setColor(Color.RED);
+ bg.fillRect(0, 0, SIZE, SIZE);
+ bg.translate(100, 100);
+ bg.rotate(Math.toRadians(90));
+ bg.setColor(Color.BLACK);
+ bg.setFont(bg.getFont().deriveFont(20.0f));
+ bg.drawString("MMMMMMMMMMMMMMMM", 0, 0);
+ bg.dispose();
+ return bi;
+ }
+}
diff --git a/test/java/awt/Graphics2D/IncorrectTextSize/IncorrectTextSize.java b/test/java/awt/Graphics2D/IncorrectTextSize/IncorrectTextSize.java
new file mode 100644
index 0000000..b4ab3a6
--- /dev/null
+++ b/test/java/awt/Graphics2D/IncorrectTextSize/IncorrectTextSize.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+/**
+ * @test
+ * @bug 8013569
+ * @author Sergey Bylokhov
+ */
+public final class IncorrectTextSize {
+
+ static final int scale = 2;
+ static final int width = 1200;
+ static final int height = 100;
+ static BufferedImage bi = new BufferedImage(width, height,
+ BufferedImage.TYPE_INT_ARGB);
+ static final String TEXT = "The quick brown fox jumps over the lazy dog"
+ + "The quick brown fox jumps over the lazy dog";
+
+ public static void main(final String[] args) throws IOException {
+ for (int point = 5; point < 11; ++point) {
+ Graphics2D g2d = bi.createGraphics();
+ g2d.setFont(new Font(Font.DIALOG, Font.PLAIN, point));
+ g2d.scale(scale, scale);
+ g2d.setColor(Color.WHITE);
+ g2d.fillRect(0, 0, width, height);
+ g2d.setColor(Color.green);
+ g2d.drawString(TEXT, 0, 20);
+ int length = g2d.getFontMetrics().stringWidth(TEXT);
+ if (length < 0) {
+ throw new RuntimeException("Negative length");
+ }
+ for (int i = (length + 1) * scale; i < width; ++i) {
+ for (int j = 0; j < height; ++j) {
+ if (bi.getRGB(i, j) != Color.white.getRGB()) {
+ g2d.drawLine(length, 0, length, height);
+ ImageIO.write(bi, "png", new File("image.png"));
+ System.out.println("length = " + length);
+ System.err.println("Wrong color at x=" + i + ",y=" + j);
+ System.err.println("Color is:" + new Color(bi.getRGB(i,
+ j)));
+ throw new RuntimeException("Test failed.");
+ }
+ }
+ }
+ g2d.dispose();
+ }
+ }
+}
diff --git a/test/javax/imageio/plugins/jpeg/JpegWriterLeakTest.java b/test/javax/imageio/plugins/jpeg/JpegWriterLeakTest.java
new file mode 100644
index 0000000..ffb2b63
--- /dev/null
+++ b/test/javax/imageio/plugins/jpeg/JpegWriterLeakTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2013, 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 8020983
+ * @summary Test verifies that jpeg writer instances are collected
+ * even if destroy() or reset() methods is not invoked.
+ *
+ * @run main JpegWriterLeakTest
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Random;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageWriter;
+import javax.imageio.stream.ImageOutputStream;
+
+public class JpegWriterLeakTest {
+
+ public static void main(String[] args) {
+ final ReferenceQueue<ImageWriter> queue = new ReferenceQueue<>();
+ final ArrayList<Reference<? extends ImageWriter>> refs = new ArrayList<>();
+
+ int count = 2;
+
+ do {
+ ImageWriter writer =
+ ImageIO.getImageWritersByFormatName("jpeg").next();
+
+ final WeakReference<? extends ImageWriter> ref =
+ new WeakReference<>(writer, queue);
+
+ refs.add(ref);
+
+
+ try {
+ final ImageOutputStream os =
+ ImageIO.createImageOutputStream(new ByteArrayOutputStream());
+ writer.setOutput(os);
+
+ writer.write(getImage());
+
+
+ // NB: dispose() or reset() workarounds the problem.
+ } catch (IOException e) {
+ } finally {
+ writer = null;
+ }
+ count--;
+ } while (count > 0);
+
+
+ System.out.println("Wait for GC...");
+
+ final long testTimeOut = 60000L;
+
+ final long startTime = System.currentTimeMillis();
+
+ while (!refs.isEmpty()) {
+ // check for the test timeout
+ final long now = System.currentTimeMillis();
+
+ if (now - startTime > testTimeOut) {
+ System.out.println();
+ throw new RuntimeException("Test FAILED.");
+ }
+
+ System.gc();
+
+ try {
+ System.out.print(".");
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ };
+
+ Reference<? extends ImageWriter> r = queue.poll();
+ if (r != null) {
+ System.out.println("Got reference: " + r);
+ refs.remove(r);
+ }
+ }
+ System.out.println("Test PASSED.");
+ }
+
+ private static BufferedImage getImage() {
+ int width = 2500;
+ int height = new Random().nextInt(2500) + 1;
+ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+
+ Graphics2D g = image.createGraphics();
+ g.setColor(Color.blue);
+ g.fillRect(0, 0, width, height);
+
+ return image;
+ }
+}
diff --git a/test/javax/print/DialogMargins.java b/test/javax/print/DialogMargins.java
index 41b3586..c046751 100644
--- a/test/javax/print/DialogMargins.java
+++ b/test/javax/print/DialogMargins.java
@@ -25,11 +25,12 @@
/**
* @test
- * @bug 4485755 6361370 6448717 5080051 6939417
+ * @bug 4485755 6361370 6448717 5080051 6939417 8016343
* @summary dialog doesn't have way to specify margins
* for 6361370, verify exception for offline printer in Windows
* for 6448717, faster display of print dialog
* for 6500903, verify status of printer if accepting jobs or not
+ * for 8016343, verify printing to non-default printer
* @author prr
* @run main/manual DialogMargins
*/
diff --git a/test/sun/awt/image/ImagingLib/SamePackingTypeTest.java b/test/sun/awt/image/ImagingLib/SamePackingTypeTest.java
new file mode 100644
index 0000000..75f946b
--- /dev/null
+++ b/test/sun/awt/image/ImagingLib/SamePackingTypeTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2013, 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 8019201
+ * @summary Test verifies that medialib glue code does not throw
+ * an ImagingOpException for certain pairs of source and
+ * destination images.
+ *
+ * @run main SamePackingTypeTest
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ConvolveOp;
+import java.awt.image.ImagingOpException;
+import java.awt.image.Kernel;
+import java.util.Arrays;
+
+
+public class SamePackingTypeTest {
+
+ public static void main(String[] args) {
+ BufferedImageOp op = createTestOp();
+
+ try {
+ System.out.print("Integer-based images... ");
+ doTest(op, TYPE_INT_ARGB, TYPE_INT_ARGB_PRE);
+ System.out.println("done.");
+
+ System.out.print("Byte-based images... ");
+ doTest(op, TYPE_4BYTE_ABGR, TYPE_4BYTE_ABGR_PRE);
+ System.out.println("done");
+ } catch (ImagingOpException e) {
+ throw new RuntimeException("Test FAILED", e);
+ }
+ }
+
+ private static void doTest(BufferedImageOp op, int stype, int dtype) {
+ final int size = 100;
+
+ final BufferedImage src = new BufferedImage(size, size, stype);
+ Graphics2D g = src.createGraphics();
+ g.setColor(Color.red);
+ g.fillRect(0, 0, size, size);
+ g.dispose();
+
+
+ final BufferedImage dst = new BufferedImage(size, size, dtype);
+ g = dst.createGraphics();
+ g.setColor(Color.blue);
+ g.fillRect(0, 0, size, size);
+ g.dispose();
+
+ op.filter(src, dst);
+
+ final int rgb = dst.getRGB(size - 1, size - 1);
+ System.out.printf("dst: 0x%X ", rgb);
+
+ if (rgb != 0xFFFF0000) {
+ throw new RuntimeException(String.format("Wrong color in dst: 0x%X", rgb));
+ }
+ }
+
+ private static BufferedImageOp createTestOp() {
+ final int size = 1;
+ final float v = 1f / (size * size);
+ final float[] k_data = new float[size * size];
+ Arrays.fill(k_data, v);
+
+ Kernel k = new Kernel(size, size, k_data);
+ return new ConvolveOp(k);
+ }
+}