# HG changeset patch # User lana # Date 1381268253 25200 # Node ID f86a5b10b7fd994df92dd8b8a8490acd47e76f96 # Parent 01c89cd66a09e77d8691a31ee8e2d73b5cb679f9# Parent 5f815efd9b8596928ee0a73bdbd3bedf23dde07d Merge diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPCompressionTypes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPCompressionTypes.java Tue Oct 08 14:37:33 2013 -0700 @@ -0,0 +1,47 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +package com.sun.imageio.plugins.bmp; + +public class BMPCompressionTypes { + + private static final String[] compressionTypeNames = + {"BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS", "BI_JPEG", "BI_PNG"}; + + static int getType(String typeString) { + for (int i = 0; i < compressionTypeNames.length; i++) + if (compressionTypeNames[i].equals(typeString)) + return i; + return 0; + } + + static String getName(int type) { + return compressionTypeNames[type]; + } + + public static String[] getCompressionTypes() { + return compressionTypeNames.clone(); + } +} diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPConstants.java Tue Oct 08 14:37:33 2013 -0700 @@ -47,7 +47,4 @@ static final int BI_BITFIELDS = 3; static final int BI_JPEG = 4; static final int BI_PNG = 5; - - static final String[] compressionTypeNames = - {"BI_RGB", "BI_RLE8", "BI_RLE4", "BI_BITFIELDS", "BI_JPEG", "BI_PNG"}; } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java Tue Oct 08 14:37:33 2013 -0700 @@ -25,7 +25,6 @@ package com.sun.imageio.plugins.bmp; -import java.awt.Point; import java.awt.Rectangle; import java.awt.image.ColorModel; import java.awt.image.ComponentSampleModel; @@ -42,7 +41,6 @@ import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import java.awt.image.SinglePixelPackedSampleModel; -import java.awt.image.WritableRaster; import java.awt.image.BufferedImage; import java.io.IOException; @@ -51,22 +49,16 @@ import java.util.Iterator; import javax.imageio.IIOImage; -import javax.imageio.IIOException; import javax.imageio.ImageIO; import javax.imageio.ImageTypeSpecifier; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.metadata.IIOMetadata; -import javax.imageio.metadata.IIOMetadataNode; -import javax.imageio.metadata.IIOMetadataFormatImpl; -import javax.imageio.metadata.IIOInvalidTreeException; import javax.imageio.spi.ImageWriterSpi; import javax.imageio.stream.ImageOutputStream; import javax.imageio.event.IIOWriteProgressListener; import javax.imageio.event.IIOWriteWarningListener; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; import javax.imageio.plugins.bmp.BMPImageWriteParam; import com.sun.imageio.plugins.common.ImageUtil; @@ -129,7 +121,7 @@ meta.compression = getPreferredCompressionType(imageType); if (param != null && param.getCompressionMode() == ImageWriteParam.MODE_EXPLICIT) { - meta.compression = getCompressionType(param.getCompressionType()); + meta.compression = BMPCompressionTypes.getType(param.getCompressionType()); } meta.bitsPerPixel = (short)imageType.getColorModel().getPixelSize(); return meta; @@ -308,7 +300,7 @@ switch(bmpParam.getCompressionMode()) { case ImageWriteParam.MODE_EXPLICIT: - compressionType = getCompressionType(bmpParam.getCompressionType()); + compressionType = BMPCompressionTypes.getType(bmpParam.getCompressionType()); break; case ImageWriteParam.MODE_COPY_FROM_METADATA: compressionType = bmpImageMetadata.compression; @@ -323,12 +315,12 @@ if (!canEncodeImage(compressionType, colorModel, sampleModel)) { throw new IOException("Image can not be encoded with compression type " - + compressionTypeNames[compressionType]); + + BMPCompressionTypes.getName(compressionType)); } byte r[] = null, g[] = null, b[] = null, a[] = null; - if (compressionType == BMPConstants.BI_BITFIELDS) { + if (compressionType == BI_BITFIELDS) { bitsPerPixel = DataBuffer.getDataTypeSize(sampleModel.getDataType()); @@ -372,7 +364,7 @@ // an exception related to unsupported image format throw new IOException("Image can not be encoded with " + "compression type " + - compressionTypeNames[compressionType]); + BMPCompressionTypes.getName(compressionType)); } } writeMaskToPalette(rmask, 0, r, g, b, a); @@ -511,8 +503,8 @@ * Images with any other compression type must be wrote in the * bottom-up layout. */ - if (compressionType == BMPConstants.BI_RGB || - compressionType == BMPConstants.BI_BITFIELDS) + if (compressionType == BI_RGB || + compressionType == BI_BITFIELDS) { isTopDown = bmpParam.isTopDown(); } else { @@ -543,7 +535,7 @@ if (isPalette == true) { // write palette - if (compressionType == BMPConstants.BI_BITFIELDS) { + if (compressionType == BI_BITFIELDS) { // write masks for red, green and blue components. for (int i=0; i<3; i++) { int mask = (a[i]&0xFF) + ((r[i]&0xFF)*0x100) + ((g[i]&0xFF)*0x10000) + ((b[i]&0xFF)*0x1000000); @@ -571,8 +563,8 @@ int l; - if (compressionType == BMPConstants.BI_JPEG || - compressionType == BMPConstants.BI_PNG) { + if (compressionType == BI_JPEG || + compressionType == BI_PNG) { // prepare embedded buffer embedded_stream = new ByteArrayOutputStream(); @@ -657,7 +649,7 @@ pos = sppsm.getOffset(startX, startY); } - if (compressionType == BMPConstants.BI_RGB || compressionType == BMPConstants.BI_BITFIELDS){ + if (compressionType == BI_RGB || compressionType == BI_BITFIELDS){ switch(dataType) { case DataBuffer.TYPE_BYTE: byte[] bdata = @@ -687,7 +679,7 @@ for(int k=0; kColorSpaceType node - public static final String[] colorSpaceTypeNames = { + static final String[] colorSpaceTypeNames = { "GRAY", null, "RGB", "RGB", "GRAY", null, "RGB" }; diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java --- a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java Tue Oct 08 14:37:33 2013 -0700 @@ -85,42 +85,42 @@ ImageInputStream stream = (ImageInputStream)source; stream.mark(); - int type = stream.readByte(); // TypeField - int fixHeaderField = stream.readByte(); - // check WBMP "header" - if (type != 0 || fixHeaderField != 0) { - // while WBMP reader does not support ext WBMP headers - stream.reset(); - return false; - } + try { + int type = stream.readByte(); // TypeField + int fixHeaderField = stream.readByte(); + // check WBMP "header" + if (type != 0 || fixHeaderField != 0) { + // while WBMP reader does not support ext WBMP headers + return false; + } - int width = ReaderUtil.readMultiByteInteger(stream); - int height = ReaderUtil.readMultiByteInteger(stream); - // check image dimension - if (width <= 0 || height <= 0) { - stream.reset(); - return false; - } + int width = ReaderUtil.readMultiByteInteger(stream); + int height = ReaderUtil.readMultiByteInteger(stream); + // check image dimension + if (width <= 0 || height <= 0) { + return false; + } - long dataLength = stream.length(); - if (dataLength == -1) { - // We can't verify that amount of data in the stream - // corresponds to image dimension because we do not know - // the length of the data stream. - // Assuming that wbmp image are used for mobile devices, - // let's introduce an upper limit for image dimension. - // In case if exact amount of raster data is unknown, - // let's reject images with dimension above the limit. + long dataLength = stream.length(); + if (dataLength == -1) { + // We can't verify that amount of data in the stream + // corresponds to image dimension because we do not know + // the length of the data stream. + // Assuming that wbmp image are used for mobile devices, + // let's introduce an upper limit for image dimension. + // In case if exact amount of raster data is unknown, + // let's reject images with dimension above the limit. + return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT); + } + + dataLength -= stream.getStreamPosition(); + + long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1); + + return (dataLength == scanSize * height); + } finally { stream.reset(); - return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT); } - - dataLength -= stream.getStreamPosition(); - stream.reset(); - - long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1); - - return (dataLength == scanSize * height); } public ImageReader createReaderInstance(Object extension) diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java --- a/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/classes/javax/imageio/plugins/bmp/BMPImageWriteParam.java Tue Oct 08 14:37:33 2013 -0700 @@ -29,6 +29,7 @@ import javax.imageio.ImageWriteParam; import com.sun.imageio.plugins.bmp.BMPConstants; +import com.sun.imageio.plugins.bmp.BMPCompressionTypes; /** * A subclass of ImageWriteParam for encoding images in @@ -78,7 +79,7 @@ super(locale); // Set compression types ("BI_RGB" denotes uncompressed). - compressionTypes = BMPConstants.compressionTypeNames.clone(); + compressionTypes = BMPCompressionTypes.getCompressionTypes(); // Set compression flag. canWriteCompressed = true; diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/classes/sun/font/FreetypeFontScaler.java --- a/jdk/src/share/classes/sun/font/FreetypeFontScaler.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/classes/sun/font/FreetypeFontScaler.java Tue Oct 08 14:37:33 2013 -0700 @@ -169,7 +169,7 @@ public synchronized void dispose() { if (nativeScaler != 0L) { - disposeNativeScaler(nativeScaler); + disposeNativeScaler(font.get(), nativeScaler); nativeScaler = 0L; } } @@ -190,7 +190,7 @@ synchronized int getGlyphCode(char charCode) throws FontScalerException { if (nativeScaler != 0L) { - return getGlyphCodeNative(nativeScaler, charCode); + return getGlyphCodeNative(font.get(), nativeScaler, charCode); } return FontScaler.getNullScaler().getGlyphCode(charCode); } @@ -245,9 +245,9 @@ private native long getLayoutTableCacheNative(long pScaler); - private native void disposeNativeScaler(long pScaler); + private native void disposeNativeScaler(Font2D font2D, long pScaler); - private native int getGlyphCodeNative(long pScaler, char charCode); + private native int getGlyphCodeNative(Font2D font, long pScaler, char charCode); private native int getNumGlyphsNative(long pScaler); private native int getMissingGlyphCodeNative(long pScaler); diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/font/freetypeScaler.c --- a/jdk/src/share/native/sun/font/freetypeScaler.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/font/freetypeScaler.c Tue Oct 08 14:37:33 2013 -0700 @@ -252,7 +252,6 @@ JNIEnv *env, jobject scaler, jobject font2D, jint type, jint indexInCollection, jboolean supportsCJK, jint filesize) { FTScalerInfo* scalerInfo = NULL; - FT_Stream ftstream; FT_Open_Args ft_open_args; int error; jobject bBuffer; @@ -309,34 +308,36 @@ } } else { /* Truetype */ scalerInfo->fontData = (unsigned char*) malloc(FILEDATACACHESIZE); - ftstream = (FT_Stream) calloc(1, sizeof(FT_StreamRec)); - if (ftstream != NULL && scalerInfo->fontData != NULL) { - scalerInfo->directBuffer = (*env)->NewDirectByteBuffer(env, - scalerInfo->fontData, - FILEDATACACHESIZE); - if (scalerInfo->directBuffer != NULL) { - scalerInfo->directBuffer = (*env)->NewGlobalRef(env, - scalerInfo->directBuffer); - ftstream->base = NULL; - ftstream->size = filesize; - ftstream->pos = 0; - ftstream->read = (FT_Stream_IoFunc) ReadTTFontFileFunc; - ftstream->close = (FT_Stream_CloseFunc) CloseTTFontFileFunc; - ftstream->pathname.pointer = (void *) scalerInfo; + if (scalerInfo->fontData != NULL) { + FT_Stream ftstream = (FT_Stream) calloc(1, sizeof(FT_StreamRec)); + if (ftstream != NULL) { + scalerInfo->directBuffer = (*env)->NewDirectByteBuffer(env, + scalerInfo->fontData, + FILEDATACACHESIZE); + if (scalerInfo->directBuffer != NULL) { + scalerInfo->directBuffer = (*env)->NewGlobalRef(env, + scalerInfo->directBuffer); + ftstream->base = NULL; + ftstream->size = filesize; + ftstream->pos = 0; + ftstream->read = (FT_Stream_IoFunc) ReadTTFontFileFunc; + ftstream->close = (FT_Stream_CloseFunc) CloseTTFontFileFunc; + ftstream->pathname.pointer = (void *) scalerInfo; - memset(&ft_open_args, 0, sizeof(FT_Open_Args)); - ft_open_args.flags = FT_OPEN_STREAM; - ft_open_args.stream = ftstream; + memset(&ft_open_args, 0, sizeof(FT_Open_Args)); + ft_open_args.flags = FT_OPEN_STREAM; + ft_open_args.stream = ftstream; - error = FT_Open_Face(scalerInfo->library, - &ft_open_args, - indexInCollection, - &scalerInfo->face); - } - if (error || scalerInfo->directBuffer == NULL) { - free(ftstream); - } + error = FT_Open_Face(scalerInfo->library, + &ft_open_args, + indexInCollection, + &scalerInfo->face); + } + if (error || scalerInfo->directBuffer == NULL) { + free(ftstream); + } + } } } @@ -902,13 +903,13 @@ */ JNIEXPORT void JNICALL Java_sun_font_FreetypeFontScaler_disposeNativeScaler( - JNIEnv *env, jobject scaler, jlong pScaler) { + JNIEnv *env, jobject scaler, jobject font2D, jlong pScaler) { FTScalerInfo* scalerInfo = (FTScalerInfo *) jlong_to_ptr(pScaler); /* Freetype functions *may* cause callback to java that can use cached values. Make sure our cache is up to date. NB: scaler context is not important at this point, can use NULL. */ - int errCode = setupFTContext(env, scaler, scalerInfo, NULL); + int errCode = setupFTContext(env, font2D, scalerInfo, NULL); if (errCode) { return; } @@ -957,7 +958,8 @@ */ JNIEXPORT jint JNICALL Java_sun_font_FreetypeFontScaler_getGlyphCodeNative( - JNIEnv *env, jobject scaler, jlong pScaler, jchar charCode) { + JNIEnv *env, jobject scaler, + jobject font2D, jlong pScaler, jchar charCode) { FTScalerInfo* scalerInfo = (FTScalerInfo *) jlong_to_ptr(pScaler); int errCode; @@ -970,7 +972,7 @@ /* Freetype functions *may* cause callback to java that can use cached values. Make sure our cache is up to date. Scaler context is not important here, can use NULL. */ - errCode = setupFTContext(env, scaler, scalerInfo, NULL); + errCode = setupFTContext(env, font2D, scalerInfo, NULL); if (errCode) { return 0; } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/Disposer.c --- a/jdk/src/share/native/sun/java2d/Disposer.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/Disposer.c Tue Oct 08 14:37:33 2013 -0700 @@ -38,10 +38,9 @@ { addRecordMID = (*env)->GetStaticMethodID(env, disposerClass, "addRecord", "(Ljava/lang/Object;JJ)V"); - if (addRecordMID == 0) { - JNU_ThrowNoSuchMethodError(env, "Disposer.addRecord"); + if (addRecordMID != 0) { + dispClass = (*env)->NewGlobalRef(env, disposerClass); } - dispClass = (*env)->NewGlobalRef(env, disposerClass); } JNIEXPORT void JNICALL @@ -50,6 +49,10 @@ if (dispClass == NULL) { /* Needed to initialize the Disposer class as it may be not yet referenced */ jclass clazz = (*env)->FindClass(env, "sun/java2d/Disposer"); + if ((*env)->ExceptionCheck(env)) { + // If there's exception pending, we'll just return. + return; + } } (*env)->CallStaticVoidMethod(env, dispClass, addRecordMID, diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/SurfaceData.c --- a/jdk/src/share/native/sun/java2d/SurfaceData.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/SurfaceData.c Tue Oct 08 14:37:33 2013 -0700 @@ -237,7 +237,9 @@ SurfaceData_SetOps(env, sData, ops); if (ops != NULL) { memset(ops, 0, opsSize); - ops->sdObject = (*env)->NewWeakGlobalRef(env, sData); + if (!(*env)->ExceptionCheck(env)) { + ops->sdObject = (*env)->NewWeakGlobalRef(env, sData); + } } return ops; } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/loops/Blit.c --- a/jdk/src/share/native/sun/java2d/loops/Blit.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/loops/Blit.c Tue Oct 08 14:37:33 2013 -0700 @@ -60,8 +60,11 @@ } srcOps = SurfaceData_GetOps(env, srcData); + if (srcOps == 0) { + return; + } dstOps = SurfaceData_GetOps(env, dstData); - if (srcOps == 0 || dstOps == 0) { + if (dstOps == 0) { return; } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/loops/BlitBg.c --- a/jdk/src/share/native/sun/java2d/loops/BlitBg.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/loops/BlitBg.c Tue Oct 08 14:37:33 2013 -0700 @@ -60,8 +60,11 @@ } srcOps = SurfaceData_GetOps(env, srcData); + if (srcOps == 0) { + return; + } dstOps = SurfaceData_GetOps(env, dstData); - if (srcOps == 0 || dstOps == 0) { + if (dstOps == 0) { return; } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/loops/DrawPath.c --- a/jdk/src/share/native/sun/java2d/loops/DrawPath.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/loops/DrawPath.c Tue Oct 08 14:37:33 2013 -0700 @@ -75,7 +75,8 @@ CompositeInfo compInfo; jint ret; NativePrimitive *pPrim = GetNativePrim(env, self); - jint stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID); + jint stroke; + jboolean throwExc = JNI_FALSE; if (pPrim == NULL) { return; @@ -84,6 +85,8 @@ GrPrim_Sg2dGetCompInfo(env, sg2d, pPrim, &compInfo); } + stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID); + sdOps = SurfaceData_GetOps(env, sData); if (sdOps == 0) { return; @@ -112,6 +115,10 @@ maxCoords = (*env)->GetArrayLength(env, coordsArray); coords = (jfloat*)(*env)->GetPrimitiveArrayCritical( env, coordsArray, NULL); + if (coords == NULL) { + SurfaceData_InvokeUnlock(env, sdOps, &rasInfo); + return; + } if (ret == SD_SLOWLOCK) { GrPrim_RefineBounds(&rasInfo.bounds, transX, transY, @@ -157,22 +164,29 @@ drawHandler.yMax = rasInfo.bounds.y2; drawHandler.pData = &dHData; - if (!doDrawPath(&drawHandler, NULL, transX, transY, - coords, maxCoords, types, numTypes, - (stroke == sunHints_INTVAL_STROKE_PURE)? - PH_STROKE_PURE : PH_STROKE_DEFAULT)) - { - JNU_ThrowArrayIndexOutOfBoundsException(env, - "coords array"); + if (types != NULL) { + if (!doDrawPath(&drawHandler, NULL, transX, transY, + coords, maxCoords, types, numTypes, + (stroke == sunHints_INTVAL_STROKE_PURE)? + PH_STROKE_PURE : PH_STROKE_DEFAULT)) + { + throwExc = JNI_TRUE; + } + + (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types, + JNI_ABORT); } - - (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types, - JNI_ABORT); } } SurfaceData_InvokeRelease(env, sdOps, &rasInfo); } (*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords, JNI_ABORT); + + if (throwExc) { + JNU_ThrowArrayIndexOutOfBoundsException(env, + "coords array"); + } + SurfaceData_InvokeUnlock(env, sdOps, &rasInfo); } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/loops/DrawPolygons.c --- a/jdk/src/share/native/sun/java2d/loops/DrawPolygons.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/loops/DrawPolygons.c Tue Oct 08 14:37:33 2013 -0700 @@ -186,10 +186,15 @@ } xPointsPtr = (*env)->GetPrimitiveArrayCritical(env, xPointsArray, NULL); - yPointsPtr = (*env)->GetPrimitiveArrayCritical(env, yPointsArray, NULL); - if (!xPointsPtr || !yPointsPtr) { + if (!xPointsPtr) { ok = JNI_FALSE; } + if (ok) { + yPointsPtr = (*env)->GetPrimitiveArrayCritical(env, yPointsArray, NULL); + if (!yPointsPtr) { + ok = JNI_FALSE; + } + } } if (ok) { diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/loops/FillPath.c --- a/jdk/src/share/native/sun/java2d/loops/FillPath.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/loops/FillPath.c Tue Oct 08 14:37:33 2013 -0700 @@ -64,7 +64,8 @@ CompositeInfo compInfo; jint ret; NativePrimitive *pPrim = GetNativePrim(env, self); - jint stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID); + jint stroke; + jboolean throwExc = JNI_FALSE; if (pPrim == NULL) { return; @@ -73,6 +74,8 @@ GrPrim_Sg2dGetCompInfo(env, sg2d, pPrim, &compInfo); } + stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID); + sdOps = SurfaceData_GetOps(env, sData); if (sdOps == 0) { return; @@ -102,6 +105,10 @@ maxCoords = (*env)->GetArrayLength(env, coordsArray); coords = (jfloat*)(*env)->GetPrimitiveArrayCritical( env, coordsArray, NULL); + if (coords == NULL) { + SurfaceData_InvokeUnlock(env, sdOps, &rasInfo); + return; + } if (ret == SD_SLOWLOCK) { GrPrim_RefineBounds(&rasInfo.bounds, transX, transY, @@ -146,24 +153,31 @@ drawHandler.yMax = rasInfo.bounds.y2; drawHandler.pData = &dHData; - if (!doFillPath(&drawHandler, - transX, transY, coords, - maxCoords, types, numTypes, - (stroke == sunHints_INTVAL_STROKE_PURE)? - PH_STROKE_PURE : PH_STROKE_DEFAULT, - fillRule)) - { - JNU_ThrowArrayIndexOutOfBoundsException(env, - "coords array"); + if (types != NULL) { + if (!doFillPath(&drawHandler, + transX, transY, coords, + maxCoords, types, numTypes, + (stroke == sunHints_INTVAL_STROKE_PURE)? + PH_STROKE_PURE : PH_STROKE_DEFAULT, + fillRule)) + { + throwExc = JNI_TRUE; + } + + (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types, + JNI_ABORT); } - - (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types, - JNI_ABORT); } } SurfaceData_InvokeRelease(env, sdOps, &rasInfo); } (*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords, JNI_ABORT); + + if (throwExc) { + JNU_ThrowArrayIndexOutOfBoundsException(env, + "coords array"); + } + SurfaceData_InvokeUnlock(env, sdOps, &rasInfo); } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.c --- a/jdk/src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/loops/GraphicsPrimitiveMgr.c Tue Oct 08 14:37:33 2013 -0700 @@ -205,33 +205,36 @@ RegisterFunc RegisterFourByteAbgr; RegisterFunc RegisterFourByteAbgrPre; - RegisterAnyByte(env); - RegisterByteBinary1Bit(env); - RegisterByteBinary2Bit(env); - RegisterByteBinary4Bit(env); - RegisterByteIndexed(env); - RegisterByteGray(env); - RegisterIndex8Gray(env); - RegisterIndex12Gray(env); - RegisterAnyShort(env); - RegisterUshort555Rgb(env); - RegisterUshort565Rgb(env); - RegisterUshort4444Argb(env); - RegisterUshort555Rgbx(env); - RegisterUshortGray(env); - RegisterUshortIndexed(env); - RegisterAny3Byte(env); - RegisterThreeByteBgr(env); - RegisterAnyInt(env); - RegisterIntArgb(env); - RegisterIntArgbPre(env); - RegisterIntArgbBm(env); - RegisterIntRgb(env); - RegisterIntBgr(env); - RegisterIntRgbx(env); - RegisterAny4Byte(env); - RegisterFourByteAbgr(env); - RegisterFourByteAbgrPre(env); + if (!RegisterAnyByte(env) || + !RegisterByteBinary1Bit(env) || + !RegisterByteBinary2Bit(env) || + !RegisterByteBinary4Bit(env) || + !RegisterByteIndexed(env) || + !RegisterByteGray(env) || + !RegisterIndex8Gray(env) || + !RegisterIndex12Gray(env) || + !RegisterAnyShort(env) || + !RegisterUshort555Rgb(env) || + !RegisterUshort565Rgb(env) || + !RegisterUshort4444Argb(env) || + !RegisterUshort555Rgbx(env) || + !RegisterUshortGray(env) || + !RegisterUshortIndexed(env) || + !RegisterAny3Byte(env) || + !RegisterThreeByteBgr(env) || + !RegisterAnyInt(env) || + !RegisterIntArgb(env) || + !RegisterIntArgbPre(env) || + !RegisterIntArgbBm(env) || + !RegisterIntRgb(env) || + !RegisterIntBgr(env) || + !RegisterIntRgbx(env) || + !RegisterAny4Byte(env) || + !RegisterFourByteAbgr(env) || + !RegisterFourByteAbgrPre(env)) + { + return; + } } #define _StartOf(T) ((T *) (&T##s)) diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/loops/MaskBlit.c --- a/jdk/src/share/native/sun/java2d/loops/MaskBlit.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/loops/MaskBlit.c Tue Oct 08 14:37:33 2013 -0700 @@ -60,8 +60,11 @@ } srcOps = SurfaceData_GetOps(env, srcData); + if (srcOps == 0) { + return; + } dstOps = SurfaceData_GetOps(env, dstData); - if (srcOps == 0 || dstOps == 0) { + if (dstOps == 0) { return; } @@ -98,6 +101,13 @@ : 0); jint savesx = srcInfo.bounds.x1; jint savedx = dstInfo.bounds.x1; + if (maskArray != NULL && pMask == NULL) { + SurfaceData_InvokeRelease(env, dstOps, &dstInfo); + SurfaceData_InvokeRelease(env, srcOps, &srcInfo); + SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); + SurfaceData_InvokeUnlock(env, srcOps, &srcInfo); + return; + } Region_StartIteration(env, &clipInfo); while (Region_NextIteration(&clipInfo, &span)) { void *pSrc = PtrCoord(srcInfo.rasBase, diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/loops/MaskFill.c --- a/jdk/src/share/native/sun/java2d/loops/MaskFill.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/loops/MaskFill.c Tue Oct 08 14:37:33 2013 -0700 @@ -84,6 +84,11 @@ (maskArray ? (*env)->GetPrimitiveArrayCritical(env, maskArray, 0) : 0); + if (maskArray != NULL && pMask == NULL) { + SurfaceData_InvokeRelease(env, sdOps, &rasInfo); + SurfaceData_InvokeUnlock(env, sdOps, &rasInfo); + return; + } maskoff += ((rasInfo.bounds.y1 - y) * maskscan + (rasInfo.bounds.x1 - x)); (*pPrim->funcs.maskfill)(pDst, diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/loops/ScaledBlit.c --- a/jdk/src/share/native/sun/java2d/loops/ScaledBlit.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/loops/ScaledBlit.c Tue Oct 08 14:37:33 2013 -0700 @@ -296,8 +296,11 @@ } srcOps = SurfaceData_GetOps(env, srcData); + if (srcOps == 0) { + return; + } dstOps = SurfaceData_GetOps(env, dstData); - if (srcOps == 0 || dstOps == 0) { + if (dstOps == 0) { return; } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/loops/TransformHelper.c --- a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c Tue Oct 08 14:37:33 2013 -0700 @@ -326,8 +326,11 @@ } srcOps = SurfaceData_GetOps(env, srcData); + if (srcOps == 0) { + return; + } dstOps = SurfaceData_GetOps(env, dstData); - if (srcOps == 0 || dstOps == 0) { + if (dstOps == 0) { return; } @@ -411,7 +414,7 @@ } if (pEdges == NULL) { - if (numedges > 0) { + if (!(*env)->ExceptionCheck(env) && numedges > 0) { JNU_ThrowInternalError(env, "Unable to allocate edge list"); } SurfaceData_InvokeUnlock(env, dstOps, &dstInfo); diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/pipe/BufferedRenderPipe.c --- a/jdk/src/share/native/sun/java2d/pipe/BufferedRenderPipe.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/pipe/BufferedRenderPipe.c Tue Oct 08 14:37:33 2013 -0700 @@ -53,6 +53,7 @@ unsigned char *bbuf; jint *ibuf; jint ipos; + jboolean hasException; J2dTraceLn2(J2D_TRACE_INFO, "BufferedRenderPipe_fillSpans: bpos=%d limit=%d", @@ -104,7 +105,10 @@ ibuf[1] = spanCount; // flush the queue - JNU_CallMethodByName(env, NULL, rq, "flushNow", "(I)V", bpos); + JNU_CallMethodByName(env, &hasException, rq, "flushNow", "(I)V", bpos); + if (hasException) { + break; + } // now start a new operation ibuf = (jint *)bbuf; diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/pipe/Region.c --- a/jdk/src/share/native/sun/java2d/pipe/Region.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/pipe/Region.c Tue Oct 08 14:37:33 2013 -0700 @@ -260,6 +260,10 @@ /* return; REMIND: What to do here? */ } Region_StartIteration(env, &clipInfo); + if ((*env)->ExceptionCheck(env)) { + return 0; + } + numrects = Region_CountIterationRects(&clipInfo); if ((unsigned long)numrects > initialBufferSize) { *pRect = (RECT_T *) SAFE_SIZE_ARRAY_ALLOC(malloc, numrects, sizeof(RECT_T)); diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/pipe/ShapeSpanIterator.c --- a/jdk/src/share/native/sun/java2d/pipe/ShapeSpanIterator.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/pipe/ShapeSpanIterator.c Tue Oct 08 14:37:33 2013 -0700 @@ -653,12 +653,15 @@ pd->curx = x; pd->cury = y; } + (*env)->ReleasePrimitiveArrayCritical(env, yArray, + yPoints, JNI_ABORT); } - (*env)->ReleasePrimitiveArrayCritical(env, yArray, - yPoints, JNI_ABORT); + (*env)->ReleasePrimitiveArrayCritical(env, xArray, + xPoints, JNI_ABORT); } - (*env)->ReleasePrimitiveArrayCritical(env, xArray, - xPoints, JNI_ABORT); + if (xPoints == NULL || yPoints == NULL) { + return; + } } if (!oom) { HANDLEENDPATH(pd, {oom = JNI_TRUE;}); diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/share/native/sun/java2d/pipe/SpanClipRenderer.c --- a/jdk/src/share/native/sun/java2d/pipe/SpanClipRenderer.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/share/native/sun/java2d/pipe/SpanClipRenderer.c Tue Oct 08 14:37:33 2013 -0700 @@ -44,21 +44,27 @@ { /* Region fields */ pBandsArrayID = (*env)->GetFieldID(env, rc, "bands", "[I"); + if (pBandsArrayID == NULL) { + return; + } pEndIndexID = (*env)->GetFieldID(env, rc, "endIndex", "I"); + if (pEndIndexID == NULL) { + return; + } /* RegionIterator fields */ pRegionID = (*env)->GetFieldID(env, ric, "region", "Lsun/java2d/pipe/Region;"); + if (pRegionID == NULL) { + return; + } pCurIndexID = (*env)->GetFieldID(env, ric, "curIndex", "I"); + if (pCurIndexID == NULL) { + return; + } pNumXbandsID = (*env)->GetFieldID(env, ric, "numXbands", "I"); - - if((pBandsArrayID == NULL) - || (pEndIndexID == NULL) - || (pRegionID == NULL) - || (pCurIndexID == NULL) - || (pNumXbandsID == NULL)) - { - JNU_ThrowInternalError(env, "NULL field ID"); + if (pNumXbandsID == NULL) { + return; } } @@ -129,10 +135,14 @@ if ((*env)->GetArrayLength(env, boxArray) < 4) { JNU_ThrowArrayIndexOutOfBoundsException(env, "band array"); + return; } alphalen = (*env)->GetArrayLength(env, alphaTile); box = (*env)->GetPrimitiveArrayCritical(env, boxArray, 0); + if (box == NULL) { + return; + } w = box[2] - box[0]; h = box[3] - box[1]; @@ -140,9 +150,14 @@ if (alphalen < offset || (alphalen - offset) / tsize < h) { (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0); JNU_ThrowArrayIndexOutOfBoundsException(env, "alpha tile array"); + return; } alpha = (*env)->GetPrimitiveArrayCritical(env, alphaTile, 0); + if (alpha == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0); + return; + } fill(alpha, offset, tsize, 0, 0, w, h, (jbyte) 0xff); @@ -182,6 +197,7 @@ if ((*env)->GetArrayLength(env, boxArray) < 4) { JNU_ThrowArrayIndexOutOfBoundsException(env, "band array"); + return; } alphalen = (*env)->GetArrayLength(env, alphaTile); @@ -196,6 +212,9 @@ } box = (*env)->GetPrimitiveArrayCritical(env, boxArray, 0); + if (box == NULL) { + return; + } lox = box[0]; loy = box[1]; @@ -207,10 +226,20 @@ (alphalen - offset - (hix-lox)) / tsize < (hiy - loy - 1)) { (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0); JNU_ThrowArrayIndexOutOfBoundsException(env, "alpha tile array"); + return; } bands = (*env)->GetPrimitiveArrayCritical(env, bandsArray, 0); + if (bands == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0); + return; + } alpha = (*env)->GetPrimitiveArrayCritical(env, alphaTile, 0); + if (alpha == NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, bandsArray, bands, 0); + (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0); + return; + } curIndex = saveCurIndex; numXbands = saveNumXbands; diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java --- a/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java Tue Oct 08 14:37:33 2013 -0700 @@ -96,6 +96,7 @@ // Now check for XRender system property boolean xRenderRequested = true; + boolean xRenderIgnoreLinuxVersion = false; String xProp = System.getProperty("sun.java2d.xrender"); if (xProp != null) { if (xProp.equals("false") || xProp.equals("f")) { @@ -104,6 +105,10 @@ xRenderRequested = true; xRenderVerbose = true; } + + if(xProp.equalsIgnoreCase("t") || xProp.equalsIgnoreCase("true")) { + xRenderIgnoreLinuxVersion = true; + } } // initialize the X11 display connection @@ -121,7 +126,7 @@ // only attempt to initialize Xrender if it was requested if (xRenderRequested) { - xRenderAvailable = initXRender(xRenderVerbose); + xRenderAvailable = initXRender(xRenderVerbose, xRenderIgnoreLinuxVersion); if (xRenderVerbose && !xRenderAvailable) { System.out.println( "Could not enable XRender pipeline"); @@ -159,7 +164,7 @@ private static boolean xRenderVerbose; private static boolean xRenderAvailable; - private static native boolean initXRender(boolean verbose); + private static native boolean initXRender(boolean verbose, boolean ignoreLinuxVersion); public static boolean isXRenderAvailable() { return xRenderAvailable; } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/solaris/classes/sun/java2d/xr/GrowableRectArray.java --- a/jdk/src/solaris/classes/sun/java2d/xr/GrowableRectArray.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/solaris/classes/sun/java2d/xr/GrowableRectArray.java Tue Oct 08 14:37:33 2013 -0700 @@ -38,6 +38,20 @@ super(RECT_SIZE, initialSize); } + public final void pushRectValues(int x, int y, int width, int height) { + int currSize = size; + size += RECT_SIZE; + + if (size >= array.length) { + growArray(); + } + + array[currSize] = x; + array[currSize + 1] = y; + array[currSize + 2] = width; + array[currSize + 3] = height; + } + public final void setX(int index, int x) { array[getCellIndex(index)] = x; } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/solaris/classes/sun/java2d/xr/MaskTile.java --- a/jdk/src/solaris/classes/sun/java2d/xr/MaskTile.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/solaris/classes/sun/java2d/xr/MaskTile.java Tue Oct 08 14:37:33 2013 -0700 @@ -41,98 +41,6 @@ dirtyArea = new DirtyRegion(); } - public void addRect(int x, int y, int width, int height) { - int index = rects.getNextIndex(); - rects.setX(index, x); - rects.setY(index, y); - rects.setWidth(index, width); - rects.setHeight(index, height); - } - - public void addLine(int x1, int y1, int x2, int y2) { - /* - * EXA is not able to accalerate diagonal lines, we try to "guide" it a - * bit to avoid excessive migration See project documentation for an - * detailed explanation - */ - DirtyRegion region = new DirtyRegion(); - region.setDirtyLineRegion(x1, y1, x2, y2); - int xDiff = region.x2 - region.x; - int yDiff = region.y2 - region.y; - - if (xDiff == 0 || yDiff == 0) { - addRect(region.x, region.y, - region.x2 - region.x + 1, region.y2 - region.y + 1); - } else if (xDiff == 1 && yDiff == 1) { - addRect(x1, y1, 1, 1); - addRect(x2, y2, 1, 1); - } else { - lineToRects(x1, y1, x2, y2); - } - } - - private void lineToRects(int xstart, int ystart, int xend, int yend) { - int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err; - - /* Entfernung in beiden Dimensionen berechnen */ - dx = xend - xstart; - dy = yend - ystart; - - /* Vorzeichen des Inkrements bestimmen */ - incx = dx > 0 ? 1 : (dx < 0) ? -1 : 0; - incy = dy > 0 ? 1 : (dy < 0) ? -1 : 0; - if (dx < 0) - dx = -dx; - if (dy < 0) - dy = -dy; - - /* feststellen, welche Entfernung groesser ist */ - if (dx > dy) { - /* x ist schnelle Richtung */ - pdx = incx; - pdy = 0; /* pd. ist Parallelschritt */ - ddx = incx; - ddy = incy; /* dd. ist Diagonalschritt */ - es = dy; - el = dx; /* Fehlerschritte schnell, langsam */ - } else { - /* y ist schnelle Richtung */ - pdx = 0; - pdy = incy; /* pd. ist Parallelschritt */ - ddx = incx; - ddy = incy; /* dd. ist Diagonalschritt */ - es = dx; - el = dy; /* Fehlerschritte schnell, langsam */ - } - - /* Initialisierungen vor Schleifenbeginn */ - x = xstart; - y = ystart; - err = el / 2; - addRect(x, y, 1, 1); - - /* Pixel berechnen */ - for (t = 0; t < el; ++t) /* t zaehlt die Pixel, el ist auch Anzahl */ - { - /* Aktualisierung Fehlerterm */ - err -= es; - if (err < 0) { - /* Fehlerterm wieder positiv (>=0) machen */ - err += el; - /* Schritt in langsame Richtung, Diagonalschritt */ - x += ddx; - y += ddy; - } else { - /* Schritt in schnelle Richtung, Parallelschritt */ - x += pdx; - y += pdy; - } - addRect(x, y, 1, 1); - // SetPixel(x,y); - // System.out.println(x+":"+y); - } - } - public void calculateDirtyAreas() { for (int i=0; i < rects.getSize(); i++) { diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/solaris/classes/sun/java2d/xr/MaskTileManager.java --- a/jdk/src/solaris/classes/sun/java2d/xr/MaskTileManager.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/solaris/classes/sun/java2d/xr/MaskTileManager.java Tue Oct 08 14:37:33 2013 -0700 @@ -54,10 +54,6 @@ int maskPixmap; int maskPicture; long maskGC; - int lineMaskPixmap; - int lineMaskPicture; - long drawLineGC; - long clearLineGC; public MaskTileManager(XRCompositeManager xrMgr, int parentXid) { tileList = new ArrayList(); @@ -71,34 +67,6 @@ 0, 0, MASK_SIZE, MASK_SIZE); maskGC = con.createGC(maskPixmap); con.setGCExposures(maskGC, false); - - lineMaskPixmap = con.createPixmap(parentXid, 8, MASK_SIZE, MASK_SIZE); - lineMaskPicture = - con.createPicture(lineMaskPixmap, XRUtils.PictStandardA8); - con.renderRectangle(lineMaskPicture, XRUtils.PictOpClear, - new XRColor(Color.black), 0, 0, MASK_SIZE, MASK_SIZE); - - drawLineGC = con.createGC(lineMaskPixmap); - con.setGCExposures(drawLineGC, false); - con.setGCForeground(drawLineGC, 255); - - clearLineGC = con.createGC(lineMaskPixmap); - con.setGCExposures(clearLineGC, false); - con.setGCForeground(clearLineGC, 0); - } - - /** - * Adds a rectangle to the mask. - */ - public void addRect(int x, int y, int width, int height) { - mainTile.addRect(x, y, width, height); - } - - /** - * Adds a line to the mask. - */ - public void addLine(int x1, int y1, int x2, int y2) { - mainTile.addLine(x1, y1, x2, y2); } /** @@ -324,4 +292,11 @@ rects.setY(index, 0); } } + + /** + * @return MainTile to which rectangles are added before composition. + */ + public MaskTile getMainTile() { + return mainTile; + } } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/solaris/classes/sun/java2d/xr/XRDrawLine.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/solaris/classes/sun/java2d/xr/XRDrawLine.java Tue Oct 08 14:37:33 2013 -0700 @@ -0,0 +1,425 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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. + */ + +/** + * Bresenham line-drawing implementation decomposing line segments + * into a series of rectangles. + * This is required, because xrender doesn't support line primitives directly. + * The code here is an almost 1:1 port of the existing C-source contained in + * sun/java2d/loop/DrawLine.c and sun/java2d/loop/LoopMacros.h + */ +package sun.java2d.xr; + +public class XRDrawLine { + static final int BIG_MAX = ((1 << 29) - 1); + static final int BIG_MIN = (-(1 << 29)); + + static final int OUTCODE_TOP = 1; + static final int OUTCODE_BOTTOM = 2; + static final int OUTCODE_LEFT = 4; + static final int OUTCODE_RIGHT = 8; + + int x1, y1, x2, y2; + int ucX1, ucY1, ucX2, ucY2; + + DirtyRegion region = new DirtyRegion(); + + protected void rasterizeLine(GrowableRectArray rectBuffer, int _x1, + int _y1, int _x2, int _y2, int cxmin, int cymin, int cxmax, + int cymax, boolean clip, boolean overflowCheck) { + float diagF; + int error; + int steps; + int errminor, errmajor; + boolean xmajor; + int dx, dy, ax, ay; + + initCoordinates(_x1, _y1, _x2, _y2, overflowCheck); + + dx = x2 - x1; + dy = y2 - y1; + ax = Math.abs(dx); + ay = Math.abs(dy); + xmajor = (ax >= ay); + diagF = ((float) ax) / ay; + + if (clip + && !clipCoordinates(cxmin, cymin, cxmax, cymax, xmajor, dx, dy, + ax, ay)) { + // whole line was clipped away + return; + } + + region.setDirtyLineRegion(x1, y1, x2, y2); + int xDiff = region.x2 - region.x; + int yDiff = region.y2 - region.y; + + if (xDiff == 0 || yDiff == 0) { + // horizontal / diagonal lines can be represented by a single + // rectangle + rectBuffer.pushRectValues(region.x, region.y, region.x2 - region.x + + 1, region.y2 - region.y + 1); + return; + } + + // Setup bresenham + if (xmajor) { + errmajor = ay * 2; + errminor = ax * 2; + ax = -ax; /* For clipping adjustment below */ + steps = x2 - x1; + } else { + errmajor = ax * 2; + errminor = ay * 2; + ay = -ay; /* For clipping adjustment below */ + steps = y2 - y1; + } + + if ((steps = (Math.abs(steps) + 1)) == 0) { + return; + } + + error = -(errminor / 2); + + if (y1 != ucY1) { + int ysteps = y1 - ucY1; + if (ysteps < 0) { + ysteps = -ysteps; + } + error += ysteps * ax * 2; + } + + if (x1 != ucX1) { + int xsteps = x1 - ucX1; + if (xsteps < 0) { + xsteps = -xsteps; + } + error += xsteps * ay * 2; + } + error += errmajor; + errminor -= errmajor; + + int xStep = (dx > 0 ? 1 : -1); + int yStep = (dy > 0 ? 1 : -1); + int orthogonalXStep = xmajor ? xStep : 0; + int orthogonalYStep = !xmajor ? yStep : 0; + + /* + * For lines which proceed in one direction faster, we try to generate + * rectangles instead of points. Otherwise we try to avoid the extra + * work... + */ + if (diagF <= 0.9 || diagF >= 1.1) { + lineToRects(rectBuffer, steps, error, errmajor, errminor, xStep, + yStep, orthogonalXStep, orthogonalYStep); + } else { + lineToPoints(rectBuffer, steps, error, errmajor, errminor, xStep, + yStep, orthogonalXStep, orthogonalYStep); + } + } + + private void lineToPoints(GrowableRectArray rectBuffer, int steps, + int error, int errmajor, int errminor, int xStep, int yStep, + int orthogonalXStep, int orthogonalYStep) { + int x = x1, y = y1; + + do { + rectBuffer.pushRectValues(x, y, 1, 1); + + // "Traditional" Bresenham line drawing + if (error < 0) { + error += errmajor; + x += orthogonalXStep; + y += orthogonalYStep; + } else { + error -= errminor; + x += xStep; + y += yStep; + } + } while (--steps > 0); + } + + private void lineToRects(GrowableRectArray rectBuffer, int steps, + int error, int errmajor, int errminor, int xStep, int yStep, + int orthogonalXStep, int orthogonalYStep) { + int x = x1, y = y1; + int rectX = Integer.MIN_VALUE, rectY = 0; + int rectW = 0, rectH = 0; + + do { + // Combine the resulting rectangles + // for steps performed in a single direction. + if (y == rectY) { + if (x == (rectX + rectW)) { + rectW++; + } else if (x == (rectX - 1)) { + rectX--; + rectW++; + } + } else if (x == rectX) { + if (y == (rectY + rectH)) { + rectH++; + } else if (y == (rectY - 1)) { + rectY--; + rectH++; + } + } else { + // Diagonal step: add the previous rectangle to the list, + // iff it was "real" (= not initialized before the first + // iteration) + if (rectX != Integer.MIN_VALUE) { + rectBuffer.pushRectValues(rectX, rectY, rectW, rectH); + } + rectX = x; + rectY = y; + rectW = rectH = 1; + } + + // "Traditional" Bresenham line drawing + if (error < 0) { + error += errmajor; + x += orthogonalXStep; + y += orthogonalYStep; + } else { + error -= errminor; + x += xStep; + y += yStep; + } + } while (--steps > 0); + + // Add last rectangle which isn't handled by the combination-code + // anymore + rectBuffer.pushRectValues(rectX, rectY, rectW, rectH); + } + + private boolean clipCoordinates(int cxmin, int cymin, int cxmax, int cymax, + boolean xmajor, int dx, int dy, int ax, int ay) { + int outcode1, outcode2; + + outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax); + outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax); + + while ((outcode1 | outcode2) != 0) { + int xsteps = 0, ysteps = 0; + + if ((outcode1 & outcode2) != 0) { + return false; + } + + if (outcode1 != 0) { + if ((outcode1 & (OUTCODE_TOP | OUTCODE_BOTTOM)) != 0) { + if ((outcode1 & OUTCODE_TOP) != 0) { + y1 = cymin; + } else { + y1 = cymax; + } + ysteps = y1 - ucY1; + if (ysteps < 0) { + ysteps = -ysteps; + } + xsteps = 2 * ysteps * ax + ay; + if (xmajor) { + xsteps += ay - ax - 1; + } + xsteps = xsteps / (2 * ay); + if (dx < 0) { + xsteps = -xsteps; + } + x1 = ucX1 + (int) xsteps; + } else if ((outcode1 & (OUTCODE_LEFT | OUTCODE_RIGHT)) != 0) { + if ((outcode1 & OUTCODE_LEFT) != 0) { + x1 = cxmin; + } else { + x1 = cxmax; + } + xsteps = x1 - ucX1; + if (xsteps < 0) { + xsteps = -xsteps; + } + ysteps = 2 * xsteps * ay + ax; + if (!xmajor) { + ysteps += ax - ay - 1; + } + ysteps = ysteps / (2 * ax); + if (dy < 0) { + ysteps = -ysteps; + } + y1 = ucY1 + (int) ysteps; + } + outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax); + } else { + if ((outcode2 & (OUTCODE_TOP | OUTCODE_BOTTOM)) != 0) { + if ((outcode2 & OUTCODE_TOP) != 0) { + y2 = cymin; + } else { + y2 = cymax; + } + ysteps = y2 - ucY2; + if (ysteps < 0) { + ysteps = -ysteps; + } + xsteps = 2 * ysteps * ax + ay; + if (xmajor) { + xsteps += ay - ax; + } else { + xsteps -= 1; + } + xsteps = xsteps / (2 * ay); + if (dx > 0) { + xsteps = -xsteps; + } + x2 = ucX2 + (int) xsteps; + } else if ((outcode2 & (OUTCODE_LEFT | OUTCODE_RIGHT)) != 0) { + if ((outcode2 & OUTCODE_LEFT) != 0) { + x2 = cxmin; + } else { + x2 = cxmax; + } + xsteps = x2 - ucX2; + if (xsteps < 0) { + xsteps = -xsteps; + } + ysteps = 2 * xsteps * ay + ax; + if (xmajor) { + ysteps -= 1; + } else { + ysteps += ax - ay; + } + ysteps = ysteps / (2 * ax); + if (dy > 0) { + ysteps = -ysteps; + } + y2 = ucY2 + (int) ysteps; + } + outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax); + } + } + + return true; + } + + private void initCoordinates(int x1, int y1, int x2, int y2, + boolean checkOverflow) { + /* + * Part of calculating the Bresenham parameters for line stepping + * involves being able to store numbers that are twice the magnitude of + * the biggest absolute difference in coordinates. Since we want the + * stepping parameters to be stored in jints, we then need to avoid any + * absolute differences more than 30 bits. Thus, we need to preprocess + * the coordinates to reduce their range to 30 bits regardless of + * clipping. We need to cut their range back before we do the clipping + * because the Bresenham stepping values need to be calculated based on + * the "unclipped" coordinates. + * + * Thus, first we perform a "pre-clipping" stage to bring the + * coordinates within the 30-bit range and then we proceed to the + * regular clipping procedure, pretending that these were the original + * coordinates all along. Since this operation occurs based on a + * constant "pre-clip" rectangle of +/- 30 bits without any + * consideration for the final clip, the rounding errors that occur here + * will depend only on the line coordinates and be invariant with + * respect to the particular device/user clip rectangles in effect at + * the time. Thus, rendering a given large-range line will be consistent + * under a variety of clipping conditions. + */ + if (checkOverflow + && (OverflowsBig(x1) || OverflowsBig(y1) || OverflowsBig(x2) || OverflowsBig(y2))) { + /* + * Use doubles to get us into range for "Big" arithmetic. + * + * The math of adjusting an endpoint for clipping can involve an + * intermediate result with twice the number of bits as the original + * coordinate range. Since we want to maintain as much as 30 bits of + * precision in the resulting coordinates, we will get roundoff here + * even using IEEE double-precision arithmetic which cannot carry 60 + * bits of mantissa. Since the rounding errors will be consistent + * for a given set of input coordinates the potential roundoff error + * should not affect the consistency of our rendering. + */ + double x1d = x1; + double y1d = y1; + double x2d = x2; + double y2d = y2; + double dxd = x2d - x1d; + double dyd = y2d - y1d; + + if (x1 < BIG_MIN) { + y1d = y1 + (BIG_MIN - x1) * dyd / dxd; + x1d = BIG_MIN; + } else if (x1 > BIG_MAX) { + y1d = y1 - (x1 - BIG_MAX) * dyd / dxd; + x1d = BIG_MAX; + } + /* Use Y1d instead of _y1 for testing now as we may have modified it */ + if (y1d < BIG_MIN) { + x1d = x1 + (BIG_MIN - y1) * dxd / dyd; + y1d = BIG_MIN; + } else if (y1d > BIG_MAX) { + x1d = x1 - (y1 - BIG_MAX) * dxd / dyd; + y1d = BIG_MAX; + } + if (x2 < BIG_MIN) { + y2d = y2 + (BIG_MIN - x2) * dyd / dxd; + x2d = BIG_MIN; + } else if (x2 > BIG_MAX) { + y2d = y2 - (x2 - BIG_MAX) * dyd / dxd; + x2d = BIG_MAX; + } + /* Use Y2d instead of _y2 for testing now as we may have modified it */ + if (y2d < BIG_MIN) { + x2d = x2 + (BIG_MIN - y2) * dxd / dyd; + y2d = BIG_MIN; + } else if (y2d > BIG_MAX) { + x2d = x2 - (y2 - BIG_MAX) * dxd / dyd; + y2d = BIG_MAX; + } + + x1 = (int) x1d; + y1 = (int) y1d; + x2 = (int) x2d; + y2 = (int) y2d; + } + + this.x1 = ucX1 = x1; + this.y1 = ucY1 = y1; + this.x2 = ucX2 = x2; + this.y2 = ucY2 = y2; + } + + private boolean OverflowsBig(int v) { + return ((v) != (((v) << 2) >> 2)); + } + + private int out(int v, int vmin, int vmax, int cmin, int cmax) { + return ((v < vmin) ? cmin : ((v > vmax) ? cmax : 0)); + } + + private int outcode(int x, int y, int xmin, int ymin, int xmax, int ymax) { + return out(y, ymin, ymax, OUTCODE_TOP, OUTCODE_BOTTOM) + | out(x, xmin, xmax, OUTCODE_LEFT, OUTCODE_RIGHT); + } +} diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java --- a/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java Tue Oct 08 14:37:33 2013 -0700 @@ -53,10 +53,15 @@ public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe { XRDrawHandler drawHandler; MaskTileManager tileManager; + XRDrawLine lineGen; + GrowableRectArray rectBuffer; public XRRenderer(MaskTileManager tileManager) { this.tileManager = tileManager; + this.rectBuffer = tileManager.getMainTile().getRects(); + this.drawHandler = new XRDrawHandler(); + this.lineGen = new XRDrawLine(); } /** @@ -77,19 +82,15 @@ int transX2 = Region.clipAdd(x2, sg2d.transX); int transY2 = Region.clipAdd(y2, sg2d.transY); - // Non clipped fast path - if (compClip.contains(transX1, transY1) - && compClip.contains(transX2, transY2)) { - SunToolkit.awtLock(); - try { - validateSurface(sg2d); - tileManager.addLine(transX1, transY1, transX2, transY2); - tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); - } finally { - SunToolkit.awtUnlock(); - } - } else { - draw(sg2d, new Line2D.Float(x1, y1, x2, y2)); + SunToolkit.awtLock(); + try { + validateSurface(sg2d); + lineGen.rasterizeLine(rectBuffer, transX1, transY1, + transX2, transY2, compClip.getLoX(), compClip.getLoY(), + compClip.getHiX(), compClip.getHiY(), true, true); + tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); + } finally { + SunToolkit.awtUnlock(); } } @@ -148,7 +149,7 @@ SunToolkit.awtLock(); try { validateSurface(sg2d); - tileManager.addRect(x, y, width, height); + rectBuffer.pushRectValues(x, y, width, height); tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); } finally { SunToolkit.awtUnlock(); @@ -199,11 +200,13 @@ } private class XRDrawHandler extends ProcessPath.DrawHandler { + DirtyRegion region; XRDrawHandler() { // these are bogus values; the caller will use validate() // to ensure that they are set properly prior to each usage super(0, 0, 0, 0); + this.region = new DirtyRegion(); } /** @@ -218,15 +221,32 @@ } public void drawLine(int x1, int y1, int x2, int y2) { - tileManager.addLine(x1, y1, x2, y2); + region.setDirtyLineRegion(x1, y1, x2, y2); + int xDiff = region.x2 - region.x; + int yDiff = region.y2 - region.y; + + if (xDiff == 0 || yDiff == 0) { + // horizontal / diagonal lines can be represented by a single + // rectangle + rectBuffer.pushRectValues(region.x, region.y, region.x2 - region.x + + 1, region.y2 - region.y + 1); + } else if (xDiff == 1 && yDiff == 1) { + // fast path for pattern commonly generated by + // ProcessPath.DrawHandler + rectBuffer.pushRectValues(x1, y1, 1, 1); + rectBuffer.pushRectValues(x2, y2, 1, 1); + } else { + lineGen.rasterizeLine(rectBuffer, x1, y1, x2, y2, 0, 0, + 0, 0, false, false); + } } public void drawPixel(int x, int y) { - tileManager.addRect(x, y, 1, 1); + rectBuffer.pushRectValues(x, y, 1, 1); } public void drawScanline(int x1, int x2, int y) { - tileManager.addRect(x1, y, x2 - x1 + 1, 1); + rectBuffer.pushRectValues(x1, y, x2 - x1 + 1, 1); } } @@ -263,7 +283,7 @@ validateSurface(sg2d); int[] spanBox = new int[4]; while (si.nextSpan(spanBox)) { - tileManager.addRect(spanBox[0] + transx, + rectBuffer.pushRectValues(spanBox[0] + transx, spanBox[1] + transy, spanBox[2] - spanBox[0], spanBox[3] - spanBox[1]); diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java --- a/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/solaris/classes/sun/java2d/xr/XRSurfaceData.java Tue Oct 08 14:37:33 2013 -0700 @@ -457,15 +457,15 @@ if (sg2d != null && sg2d.compositeState == SunGraphics2D.COMP_XOR) { if (validatedXorComp != sg2d.getComposite()) { validatedXorComp = (XORComposite) sg2d.getComposite(); - int xorpixelmod = validatedXorComp.getXorPixel(); renderQueue.setGCMode(xgc, false); + } - // validate pixel - int pixel = sg2d.pixel; - if (validatedGCForegroundPixel != pixel) { - renderQueue.setGCForeground(xgc, pixel ^ xorpixelmod); - validatedGCForegroundPixel = pixel; - } + // validate pixel + int pixel = sg2d.pixel; + if (validatedGCForegroundPixel != pixel) { + int xorpixelmod = validatedXorComp.getXorPixel(); + renderQueue.setGCForeground(xgc, pixel ^ xorpixelmod); + validatedGCForegroundPixel = pixel; } if (updateGCClip) { diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/solaris/native/sun/java2d/x11/X11Renderer.c --- a/jdk/src/solaris/native/sun/java2d/x11/X11Renderer.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/solaris/native/sun/java2d/x11/X11Renderer.c Tue Oct 08 14:37:33 2013 -0700 @@ -465,9 +465,7 @@ points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy, pTmp, (int *)&npoints, isclosed); - if (points == 0) { - JNU_ThrowOutOfMemoryError(env, "translated coordinate array"); - } else { + if (points != 0) { if (npoints == 2) { /* * Some X11 implementations fail to draw anything for @@ -588,6 +586,7 @@ NULL }; PHStroke stroke; + jboolean ok = JNI_TRUE; if (xsdo == NULL) { return; @@ -625,8 +624,6 @@ types = (jbyte*) (*env)->GetPrimitiveArrayCritical(env, typesArray, NULL); if (types != NULL) { - jboolean ok; - if (isFill) { drawHandler.pDrawScanline = &drawScanline; ok = doFillPath(&drawHandler, @@ -643,14 +640,14 @@ types, numTypes, stroke); } - if (!ok) { - JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array"); - } (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types, JNI_ABORT); } (*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords, JNI_ABORT); + if (!ok) { + JNU_ThrowArrayIndexOutOfBoundsException(env, "coords array"); + } } XDHD_FREE_POINTS(&dHData); @@ -893,9 +890,7 @@ points = transformPoints(env, xcoordsArray, ycoordsArray, transx, transy, pTmp, (int *)&npoints, JNI_FALSE); - if (points == 0) { - JNU_ThrowOutOfMemoryError(env, "translated coordinate array"); - } else { + if (points != 0) { if (npoints > 2) { XFillPolygon(awt_display, xsdo->drawable, (GC) xgc, points, npoints, Complex, CoordModeOrigin); diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c --- a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c Tue Oct 08 14:37:33 2013 -0700 @@ -227,7 +227,7 @@ #if defined(HEADLESS) || !defined(MITSHM) return JNI_FALSE; #else - return useMitShmPixmaps; + return (jboolean)useMitShmPixmaps; #endif /* HEADLESS, MITSHM */ } @@ -258,6 +258,7 @@ { #ifndef HEADLESS X11SDOps *xsdo = (X11SDOps*)SurfaceData_InitOps(env, xsd, sizeof(X11SDOps)); + jboolean hasException; if (xsdo == NULL) { JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed."); return; @@ -270,7 +271,10 @@ xsdo->ReleasePixmapWithBg = X11SD_ReleasePixmapWithBg; xsdo->widget = NULL; if (peer != NULL) { - xsdo->drawable = JNU_CallMethodByName(env, NULL, peer, "getWindow", "()J").j; + xsdo->drawable = JNU_CallMethodByName(env, &hasException, peer, "getWindow", "()J").j; + if (hasException) { + return; + } } else { xsdo->drawable = 0; } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c --- a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c Tue Oct 08 14:37:33 2013 -0700 @@ -31,6 +31,10 @@ #include +#ifdef __linux__ + #include +#endif + /* On Solaris 10 updates 8, 9, the render.h file defines these * protocol values but does not define the structs in Xrender.h. * Thus in order to get these always defined on Solaris 10 @@ -131,7 +135,7 @@ #define MAX_PAYLOAD (262140u - 36u) #define MAXUINT (0xffffffffu) -static jboolean IsXRenderAvailable(jboolean verbose) { +static jboolean IsXRenderAvailable(jboolean verbose, jboolean ignoreLinuxVersion) { void *xrenderlib; @@ -253,6 +257,31 @@ } #endif +#ifdef __linux__ + /* + * Check for Linux >= 3.5 (Ubuntu 12.04.02 LTS) to avoid hitting + * https://bugs.freedesktop.org/show_bug.cgi?id=48045 + */ + struct utsname utsbuf; + if(uname(&utsbuf) >= 0) { + int major, minor, revision; + if(sscanf(utsbuf.release, "%i.%i.%i", &major, &minor, &revision) == 3) { + if(major < 3 || (major == 3 && minor < 5)) { + if(!ignoreLinuxVersion) { + available = JNI_FALSE; + } + else if(verbose) { + printf("WARNING: Linux < 3.5 detected.\n" + "The pipeline will be enabled, but graphical " + "artifacts can occur with old graphic drivers.\n" + "See the release notes for more details.\n"); + fflush(stdout); + } + } + } + } +#endif // __linux__ + return available; } /* @@ -262,7 +291,7 @@ */ JNIEXPORT jboolean JNICALL Java_sun_awt_X11GraphicsEnvironment_initXRender -(JNIEnv *env, jclass x11ge, jboolean verbose) +(JNIEnv *env, jclass x11ge, jboolean verbose, jboolean ignoreLinuxVersion) { #ifndef HEADLESS static jboolean xrenderAvailable = JNI_FALSE; @@ -277,7 +306,7 @@ } #endif AWT_LOCK(); - xrenderAvailable = IsXRenderAvailable(verbose); + xrenderAvailable = IsXRenderAvailable(verbose, ignoreLinuxVersion); AWT_UNLOCK(); firstTime = JNI_FALSE; } @@ -297,7 +326,13 @@ jlong fmt32; jfieldID a8ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_A8", "J"); + if (a8ID == NULL) { + return; + } jfieldID argb32ID = (*env)->GetStaticFieldID(env, cls, "FMTPTR_ARGB32", "J"); + if (argb32ID == NULL) { + return; + } if (awt_display == (Display *)NULL) { return; @@ -317,6 +352,10 @@ defaultImg = XCreateImage(awt_display, NULL, 8, ZPixmap, 0, maskData, 32, 32, 8, 0); defaultImg->data = maskData; //required? maskImgID = (*env)->GetStaticFieldID(env, cls, "MASK_XIMG", "J"); + if (maskImgID == NULL) { + return; + } + (*env)->SetStaticLongField(env, cls, maskImgID, ptr_to_jlong(defaultImg)); } diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c --- a/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/solaris/native/sun/java2d/x11/XRSurfaceData.c Tue Oct 08 14:37:33 2013 -0700 @@ -88,7 +88,13 @@ J2dTraceLn(J2D_TRACE_INFO, "in XRSurfaceData_initIDs"); pictID = (*env)->GetFieldID(env, xsd, "picture", "I"); + if (pictID == NULL) { + return; + } xidID = (*env)->GetFieldID(env, xsd, "xid", "I"); + if (xidID == NULL) { + return; + } XShared_initIDs(env, JNI_FALSE); #endif /* !HEADLESS */ diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java --- a/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java Wed Oct 02 13:26:45 2013 -0700 +++ b/jdk/src/windows/classes/sun/awt/windows/WPrinterJob.java Tue Oct 08 14:37:33 2013 -0700 @@ -96,7 +96,6 @@ import javax.print.attribute.standard.JobMediaSheetsSupported; import javax.print.attribute.standard.PageRanges; import javax.print.attribute.Size2DSyntax; -import javax.print.StreamPrintService; import sun.awt.Win32FontManager; @@ -440,7 +439,7 @@ throw new HeadlessException(); } - if (getPrintService() instanceof StreamPrintService) { + if (!(getPrintService() instanceof Win32PrintService)) { return super.pageDialog(page); } @@ -586,7 +585,7 @@ attributes = new HashPrintRequestAttributeSet(); } - if (getPrintService() instanceof StreamPrintService) { + if (!(getPrintService() instanceof Win32PrintService)) { return super.printDialog(attributes); } @@ -611,7 +610,7 @@ public void setPrintService(PrintService service) throws PrinterException { super.setPrintService(service); - if (service instanceof StreamPrintService) { + if (!(service instanceof Win32PrintService)) { return; } driverDoesMultipleCopies = false; @@ -648,7 +647,7 @@ } myService = PrintServiceLookup.lookupDefaultPrintService(); - if (myService != null) { + if (myService instanceof Win32PrintService) { try { setNativePrintServiceIfNeeded(myService.getName()); } catch (Exception e) { diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/test/java/awt/Graphics/LineClipTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/Graphics/LineClipTest.java Tue Oct 08 14:37:33 2013 -0700 @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2002, 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 4780022 4862193 7179526 + * @summary Tests that clipped lines are drawn over the same pixels + * as unclipped lines (within the clip bounds) + * @run main/timeout=600/othervm -Dsun.java2d.ddforcevram=true LineClipTest + * @run main/timeout=600/othervm LineClipTest + */ + + +/** + * This app tests whether we are drawing clipped lines the same + * as unclipped lines. The problem occurred when we started + * clipping d3d lines using simple integer clipping, which did not + * account for sub-pixel precision and ended up drawing very different + * pixels than the same line drawn unclipped. A supposed fix + * to that problem used floating-point clipping instead, but there + * was some problem with very limited precision inside of d3d + * (presumably in hardware) that caused some variation in pixels. + * We decided that whatever the fix was, we needed a serious + * line check test to make sure that all kinds of different + * lines would be drawn exactly the same inside the clip area, + * regardless of whether clipping was enabled. This test should + * check all kinds of different cases, such as lines that fall + * completely outside, completely inside, start outside and + * end inside, etc., and lines should end and originate in + * all quadrants of the space divided up by the clip box. + * + * The test works as follows: + * We create nine quadrants using the spaces bisected by the + * edges of the clip bounds (note that only one of these + * quadrants is actually visible when clipping is enabled). + * We create several points in each of these quadrants + * (three in each of the invisible quadrants, nine in the + * center/visible quadrant). Our resulting grid looks like + * this: + * + * x x|x x x|x x + * | | + * | | + * | | + * | | + * | | + * x | | x + * ----------------------------------- + * x |x x x| x + * | | + * | | + * x |x x x| x + * | | + * | | + * x |x x x| x + * ----------------------------------- + * x | | x + * | | + * | | + * | | + * | | + * | | + * x x|x x x|x x + * + * The test then draws lines from every point to every other + * point. First, we draw unclipped lines in blue and + * then we draw clipped lines in red. + * At certain times (after every point during the default + * test, after every quadrant of lines if you run with the -quick + * option), we check for errors and draw the current image + * to the screen. Error checking consists of copying the + * VolatileImage to a BufferedImage (because we need access + * to the pixels directly) and checking every pixel in the + * image. The check is simple: everything outside the + * clip bounds should be blue (or the background color) and + * everything inside the clip bounds should be red (or the + * background color). So any blue pixel inside or red + * pixel outside means that there was a drawing error and + * the test fails. + * There are 4 modes that the test can run in (dynamic mode is + * exclusive to the other modes, but the other modes are combinable): + * + * (default): the clip is set + * to a default size (100x100) and the test is run. + * + * -quick: The error + * check is run only after every quadrant of lines is + * drawn. This speeds up the test considerably with + * some less accuracy in error checking (because pixels + * from some lines may overdrawn pixels from other lines + * before we have verified the correctness of those + * pixels). + * + * -dynamic: There is no error checking, but this version + * of the test automatically resizes the clip bounds and + * reruns the test over and over. Nothing besides the + * visual check verifies that the test is running correctly. + * + * -rect: Instead of drawing lines, the test draws rectangles + * to/from all points in all quadrants. This tests similar + * clipping functionality for drawRect(). + * + * n (where "n" is a number): sets the clip size to the + * given value. Just like the default test except that + * the clip size is as specified. + * + * Note: this test must be run with the -Dsun.java2d.ddforcevram=true + * option to force the test image to stay in VRAM. We currently + * punt VRAM images to system memory when we detect lots of + * reads. Since we read the whole buffer on every error check + * to copy it to the BufferedImage), this causes us to punt the + * buffer. A system memory surface will have no d3d capabilities, + * thus we are not testing the d3d line quality when this happens. + * By using the ddforcevram flag, we make sure the buffer + * stays put in VRAM and d3d is used to draw the lines. + */ + +import javax.swing.*; +import java.awt.*; +import java.awt.image.*; + + +public class LineClipTest extends Component implements Runnable { + + int clipBumpVal = 5; + static int clipSize = 100; + int clipX1; + int clipY1; + static final int NUM_QUADS = 9; + Point quadrants[][] = new Point[NUM_QUADS][]; + static boolean dynamic = false; + BufferedImage imageChecker = null; + Color unclippedColor = Color.blue; + Color clippedColor = Color.red; + int testW = -1, testH = -1; + VolatileImage testImage = null; + static boolean keepRunning = false; + static boolean quickTest = false; + static boolean rectTest = false; + static boolean runTestDone = false; + static Frame f = null; + + /** + * Check for errors in the grid. This error check consists of + * copying the buffer into a BufferedImage and reading all pixels + * in that image. No pixel outside the clip bounds should be + * of the color clippedColor and no pixel inside should be + * of the color unclippedColor. Any wrong color returns an error. + */ + boolean gridError(Graphics g) { + boolean error = false; + if (imageChecker == null || (imageChecker.getWidth() != testW) || + (imageChecker.getHeight() != testH)) + { + // Recreate BufferedImage as necessary + GraphicsConfiguration gc = getGraphicsConfiguration(); + ColorModel cm = gc.getColorModel(); + WritableRaster wr = + cm.createCompatibleWritableRaster(getWidth(), getHeight()); + imageChecker = + new BufferedImage(cm, wr, + cm.isAlphaPremultiplied(), null); + } + // Copy buffer to BufferedImage + Graphics gChecker = imageChecker.getGraphics(); + gChecker.drawImage(testImage, 0, 0, this); + + // Set up pixel colors to check against + int clippedPixelColor = clippedColor.getRGB(); + int unclippedPixelColor = unclippedColor.getRGB(); + int wrongPixelColor = clippedPixelColor; + boolean insideClip = false; + for (int row = 0; row < getHeight(); ++row) { + for (int col = 0; col < getWidth(); ++col) { + if (row >= clipY1 && row < (clipY1 + clipSize) && + col >= clipX1 && col < (clipX1 + clipSize)) + { + // Inside clip bounds - should not see unclipped color + wrongPixelColor = unclippedPixelColor; + } else { + // Outside clip - should not see clipped color + wrongPixelColor = clippedPixelColor; + } + int pixel = imageChecker.getRGB(col, row); + if (pixel == wrongPixelColor) { + System.out.println("FAILED: pixel = " + + Integer.toHexString(pixel) + + " at (x, y) = " + col + ", " + row); + // Draw magenta rectangle around problem pixel in buffer + // for visual feedback to user + g.setColor(Color.magenta); + g.drawRect(col - 1, row - 1, 2, 2); + error = true; + } + } + } + return error; + } + + /** + * Draw all test lines and check for errors (unless running + * with -dynamic option) + */ + void drawLineGrid(Graphics screenGraphics, Graphics g) { + // Fill buffer with background color + g.setColor(Color.white); + g.fillRect(0, 0, getWidth(), getHeight()); + + // Now, iterate through all quadrants + for (int srcQuad = 0; srcQuad < NUM_QUADS; ++srcQuad) { + // Draw lines to all other quadrants + for (int dstQuad = 0; dstQuad < NUM_QUADS; ++dstQuad) { + for (int srcPoint = 0; + srcPoint < quadrants[srcQuad].length; + ++srcPoint) + { + // For every point in the source quadrant + int sx = quadrants[srcQuad][srcPoint].x; + int sy = quadrants[srcQuad][srcPoint].y; + for (int dstPoint = 0; + dstPoint < quadrants[dstQuad].length; + ++dstPoint) + { + int dx = quadrants[dstQuad][dstPoint].x; + int dy = quadrants[dstQuad][dstPoint].y; + if (!rectTest) { + // Draw unclipped/clipped lines to every + // point in the dst quadrant + g.setColor(unclippedColor); + g.drawLine(sx, sy, dx, dy); + g.setClip(clipX1, clipY1, clipSize, clipSize); + g.setColor(clippedColor); + g.drawLine(sx,sy, dx, dy); + } else { + // Draw unclipped/clipped rectangles to every + // point in the dst quadrant + g.setColor(unclippedColor); + int w = dx - sx; + int h = dy - sy; + g.drawRect(sx, sy, w, h); + g.setClip(clipX1, clipY1, clipSize, clipSize); + g.setColor(clippedColor); + g.drawRect(sx, sy, w, h); + } + g.setClip(null); + } + if (!dynamic) { + // Draw screen update for visual feedback + screenGraphics.drawImage(testImage, 0, 0, this); + // On default test, check for errors after every + // src point + if (!quickTest && gridError(g)) { + throw new java.lang.RuntimeException("Failed"); + } + } + } + } + if (!dynamic && quickTest && gridError(g)) { + // On quick test, check for errors only after every + // src quadrant + throw new java.lang.RuntimeException("Failed"); + //return; + } + } + if (!dynamic) { + System.out.println("PASSED"); + if (!keepRunning) { + f.dispose(); + } + } + } + + /** + * If we have not yet run the test, or if the window size has + * changed, or if we are running the test in -dynamic mode, + * run the test. Then draw the test buffer to the screen + */ + public void paint(Graphics g) { + if (dynamic || testImage == null || + getWidth() != testW || getHeight() != testH) + { + runTest(g); + } + if (testImage != null) { + g.drawImage(testImage, 0, 0, this); + } + } + + /* + * Create the quadrant of points and run the test to draw all the lines + */ + public void runTest(Graphics screenGraphics) { + if (getWidth() == 0 || getHeight() == 0) { + // May get here before window is really ready + return; + } + clipX1 = (getWidth() - clipSize) / 2; + clipY1 = (getHeight() - clipSize) / 2; + int clipX2 = clipX1 + clipSize; + int clipY2 = clipY1 + clipSize; + int centerX = getWidth()/2; + int centerY = getHeight()/2; + int leftX = 0; + int topY = 0; + int rightX = getWidth() - 1; + int bottomY = getHeight() - 1; + int quadIndex = 0; + // Offsets are used to force diagonal (versus hor/vert) lines + int xOffset = 0; + int yOffset = 0; + + if (quadrants[0] == null) { + for (int i = 0; i < 9; ++i) { + int numPoints = (i == 4) ? 9 : 3; + quadrants[i] = new Point[numPoints]; + } + } + // Upper-left + quadrants[quadIndex] = new Point[] { + new Point(leftX + xOffset, clipY1 - 1 - yOffset), + new Point(leftX + xOffset, topY + yOffset), + new Point(clipX1 - 1 - xOffset, topY + yOffset), + }; + + quadIndex++; + yOffset++; + // Upper-middle + quadrants[quadIndex] = new Point[] { + new Point(clipX1 + 1 + xOffset, topY + yOffset), + new Point(centerX + xOffset, topY + yOffset), + new Point(clipX2 - 1 - xOffset, topY + yOffset), + }; + + quadIndex++; + ++yOffset; + // Upper-right + quadrants[quadIndex] = new Point[] { + new Point(clipX2 + 1 + xOffset, topY + yOffset), + new Point(rightX - xOffset, topY + yOffset), + new Point(rightX - xOffset, clipY1 - 1 - yOffset), + }; + + quadIndex++; + yOffset = 0; + ++xOffset; + // Middle-left + quadrants[quadIndex] = new Point[] { + new Point(leftX + xOffset, clipY1 + 1 + yOffset), + new Point(leftX + xOffset, centerY + yOffset), + new Point(leftX + xOffset, clipY2 - 1 - yOffset), + }; + + quadIndex++; + ++yOffset; + // Middle-middle + quadrants[quadIndex] = new Point[] { + new Point(clipX1 + 1 + xOffset, clipY1 + 1 + yOffset), + new Point(centerX + xOffset, clipY1 + 1 + yOffset), + new Point(clipX2 - 1 - xOffset, clipY1 + 1 + yOffset), + new Point(clipX1 + 1 + xOffset, centerY + yOffset), + new Point(centerX + xOffset, centerY + yOffset), + new Point(clipX2 - 1 - xOffset, centerY + yOffset), + new Point(clipX1 + 1 + xOffset, clipY2 - 1 - yOffset), + new Point(centerX + xOffset, clipY2 - 1 - yOffset), + new Point(clipX2 - 1 - xOffset, clipY2 - 1 - yOffset), + }; + + quadIndex++; + ++yOffset; + // Middle-right + quadrants[quadIndex] = new Point[] { + new Point(rightX - xOffset, clipY1 + 1 + yOffset), + new Point(rightX - xOffset, centerY + yOffset), + new Point(rightX - xOffset, clipY2 - 1 - yOffset), + }; + + quadIndex++; + yOffset = 0; + ++xOffset; + // Lower-left + quadrants[quadIndex] = new Point[] { + new Point(leftX + xOffset, clipY2 + 1 + yOffset), + new Point(leftX + xOffset, bottomY - yOffset), + new Point(clipX1 - 1 - xOffset, bottomY - yOffset), + }; + + quadIndex++; + ++yOffset; + // Lower-middle + quadrants[quadIndex] = new Point[] { + new Point(clipX1 + 1 + xOffset, bottomY - yOffset), + new Point(centerX + xOffset, bottomY - yOffset), + new Point(clipX2 - 1 - xOffset, bottomY - yOffset), + }; + + quadIndex++; + ++yOffset; + // Lower-right + quadrants[quadIndex] = new Point[] { + new Point(clipX2 + 1 + xOffset, bottomY - yOffset), + new Point(rightX - xOffset, bottomY - yOffset), + new Point(rightX - xOffset, clipY2 + 1 + yOffset), + }; + + + if (testImage != null) { + testImage.flush(); + } + testW = getWidth(); + testH = getHeight(); + testImage = createVolatileImage(testW, testH); + Graphics g = testImage.getGraphics(); + do { + int valCode = testImage.validate(getGraphicsConfiguration()); + if (valCode == VolatileImage.IMAGE_INCOMPATIBLE) { + testImage.flush(); + testImage = createVolatileImage(testW, testH); + g = testImage.getGraphics(); + } + drawLineGrid(screenGraphics, g); + } while (testImage.contentsLost()); + if (dynamic) { + // Draw clip box if dynamic + g.setClip(null); + g.setColor(Color.black); + g.drawRect(clipX1, clipY1, clipSize, clipSize); + screenGraphics.drawImage(testImage, 0, 0, this); + } + runTestDone = true; + } + + /** + * When running -dynamic, resize the clip bounds and run the test + * over and over + */ + public void run() { + while (true) { + clipSize += clipBumpVal; + if (clipSize > getWidth() || clipSize < 0) { + clipBumpVal = -clipBumpVal; + clipSize += clipBumpVal; + } + update(getGraphics()); + try { + Thread.sleep(50); + } catch (Exception e) {} + } + } + + public static void main(String args[]) { + for (int i = 0; i < args.length; ++i) { + if (args[i].equals("-dynamic")) { + dynamic = true; + } else if (args[i].equals("-rect")) { + rectTest = true; + } else if (args[i].equals("-quick")) { + quickTest = true; + } else if (args[i].equals("-keep")) { + keepRunning = true; + } else { + // could be clipSize + try { + clipSize = Integer.parseInt(args[i]); + } catch (Exception e) {} + } + } + f = new Frame(); + f.setSize(500, 500); + LineClipTest test = new LineClipTest(); + f.add(test); + if (dynamic) { + Thread t = new Thread(test); + t.start(); + } + f.setVisible(true); + while (!runTestDone) { + // need to make sure jtreg doesn't exit before the + // test is done... + try { + Thread.sleep(50); + } catch (Exception e) {} + } + } +} diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintDialog.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintDialog.java Tue Oct 08 14:37:33 2013 -0700 @@ -0,0 +1,59 @@ +/* + * 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.*; +import java.awt.print.PrinterJob; +import javax.print.PrintServiceLookup; + +/** + * @test + * @bug 6870661 + * @summary Verify that no native dialog is opened for a custom PrintService + * @run main/manual PrintDialog + * @author reinhapa + */ +public class PrintDialog { + + private static final String instructions = + "This test shows a non native print dialog having a 'test' print service\n" + + "selected. No other options are selectable on the General tab. The other\n" + + "tabs are as follows:\n" + + "Page Setup: Media & Margins enabled, Orientation disabled\n" + + "Appearance: All parts disabled\n\n" + + "Test passes if the dialog is shown as described above."; + + public static void main(String[] args) throws Exception { + // instruction dialog + Frame instruction = new Frame("Verify that no native print dialog is showed"); + instruction.add(new TextArea(instructions)); + instruction.pack(); + instruction.show(); + // test begin + PrintServiceStub service = new PrintServiceStub("test"); + PrintServiceLookup.registerService(service); + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintService(service); + job.printDialog(); + System.out.println("test passed"); + } +} diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintServiceStub.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/print/PrinterJob/CustomPrintService/PrintServiceStub.java Tue Oct 08 14:37:33 2013 -0700 @@ -0,0 +1,160 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.print.DocFlavor; +import javax.print.DocPrintJob; +import javax.print.PrintService; +import javax.print.ServiceUIFactory; +import javax.print.attribute.Attribute; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashPrintServiceAttributeSet; +import javax.print.attribute.PrintServiceAttribute; +import javax.print.attribute.PrintServiceAttributeSet; +import javax.print.attribute.standard.Media; +import javax.print.attribute.standard.MediaSizeName; +import javax.print.attribute.standard.PrinterInfo; +import javax.print.attribute.standard.PrinterIsAcceptingJobs; +import javax.print.attribute.standard.PrinterMakeAndModel; +import javax.print.attribute.standard.PrinterName; +import javax.print.attribute.standard.PrinterState; +import javax.print.event.PrintServiceAttributeListener; + +/** + * Stub implementation of a custom {@link PrintService}. + * + * @author reinhapa + */ +public class PrintServiceStub implements PrintService { + private final String _name; + private final Set _flavors; + private final Map, Object> _attributes; + + public PrintServiceStub(String name) { + _name = name; + _flavors = new HashSet(); + _flavors.add(DocFlavor.SERVICE_FORMATTED.PAGEABLE); + _flavors.add(DocFlavor.SERVICE_FORMATTED.PRINTABLE); + _attributes = new HashMap<>(); + _attributes.put(PrinterName.class, new PrinterName(name, null)); + _attributes.put(PrinterState.class, PrinterState.IDLE); + _attributes.put(PrinterInfo.class, new PrinterInfo("Custom location", + null)); + _attributes.put(PrinterIsAcceptingJobs.class, + PrinterIsAcceptingJobs.ACCEPTING_JOBS); + _attributes.put(PrinterMakeAndModel.class, new PrinterMakeAndModel( + "Custom printer", null)); + _attributes.put(Media.class, new Media[] { MediaSizeName.ISO_A4 }); + } + + @Override + public String getName() { + return _name; + } + + @Override + public boolean isDocFlavorSupported(DocFlavor flavor) { + return _flavors.contains(flavor); + } + + @Override + public Object getSupportedAttributeValues( + Class category, DocFlavor flavor, + AttributeSet attributes) { + return _attributes.get(category); + } + + @Override + public boolean isAttributeCategorySupported( + Class category) { + return _attributes.containsKey(category); + } + + @Override + public T getAttribute(Class category) { + return category.cast(_attributes.get(category)); + } + + @Override + public PrintServiceAttributeSet getAttributes() { + return new HashPrintServiceAttributeSet(_attributes.values().toArray( + new PrintServiceAttribute[_attributes.size()])); + } + + @Override + public DocFlavor[] getSupportedDocFlavors() { + return _flavors.toArray(new DocFlavor[_flavors.size()]); + } + + // not implemented methods + + @Override + public DocPrintJob createPrintJob() { + return null; + } + + @Override + public void addPrintServiceAttributeListener( + PrintServiceAttributeListener listener) { + + } + + @Override + public void removePrintServiceAttributeListener( + PrintServiceAttributeListener listener) { + + } + + @Override + public Class[] getSupportedAttributeCategories() { + return null; + } + + @Override + public Object getDefaultAttributeValue(Class category) { + return null; + } + + @Override + public boolean isAttributeValueSupported(Attribute attrval, + DocFlavor flavor, AttributeSet attributes) { + return false; + } + + @Override + public AttributeSet getUnsupportedAttributes(DocFlavor flavor, + AttributeSet attributes) { + return null; + } + + @Override + public ServiceUIFactory getServiceUIFactory() { + return null; + } +} diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/test/java/awt/print/PrinterJob/CustomPrintService/SetPrintServiceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/print/PrinterJob/CustomPrintService/SetPrintServiceTest.java Tue Oct 08 14:37:33 2013 -0700 @@ -0,0 +1,48 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.print.PrinterException; +import java.awt.print.PrinterJob; + +/** + * @test + * @bug 6870661 + * @summary tests setPrintService() with a custom implementation + * @author reinhapa + */ +public class SetPrintServiceTest { + + public static void main(String[] args) { + PrintServiceStub service = new PrintServiceStub("CustomPrintService"); + PrinterJob printerJob = PrinterJob.getPrinterJob(); + try { + printerJob.setPrintService(service); + System.out.println("Test Passed"); + } catch (PrinterException e) { + throw new RuntimeException("Test FAILED", e); + } + } + +} diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/test/javax/imageio/plugins/wbmp/StreamResetTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/imageio/plugins/wbmp/StreamResetTest.java Tue Oct 08 14:37:33 2013 -0700 @@ -0,0 +1,97 @@ +/* + * 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 8022632 + * @summary Test verifies that SPI of WBMP image reader + * restores the stream position if an IOException + * occurs during processing of image header. + * @run main StreamResetTest + */ + + +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.stream.ImageInputStreamImpl; + +public class StreamResetTest { + + public static void main(String[] args) { + IOException expectedException = null; + TestStream iis = new TestStream(); + + ImageReader wbmp = ImageIO.getImageReadersByFormatName("WBMP").next(); + if (wbmp == null) { + System.out.println("No WBMP reader: skip the test"); + return; + } + + ImageReaderSpi spi = wbmp.getOriginatingProvider(); + + iis.checkPosition(); + + try { + spi.canDecodeInput(iis); + } catch (IOException e) { + expectedException = e; + } + + if (expectedException == null) { + throw new RuntimeException("Test FAILED: stream was not used"); + } + + iis.checkPosition(); + + System.out.println("Test PASSED"); + + } + + private static class TestStream extends ImageInputStreamImpl { + private final int errorPos = 1; + + @Override + public int read() throws IOException { + if (streamPos == errorPos) { + throw new IOException("Test exception"); + } + streamPos++; + + return 0x03; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + streamPos += len; + return len; + } + + public void checkPosition() { + if (streamPos != 0) { + throw new RuntimeException("Test FAILED"); + } + } + } +} diff -r 01c89cd66a09 -r f86a5b10b7fd jdk/test/sun/java2d/AcceleratedXORModeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/java2d/AcceleratedXORModeTest.java Tue Oct 08 14:37:33 2013 -0700 @@ -0,0 +1,143 @@ +/* + * 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 8024343 +* @summary Test verifies that accelerated pipelines +* correctly draws primitives in XOR mode. +* @run main/othervm -Dsun.java2d.xrender=True AcceleratedXORModeTest +*/ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsEnvironment; +import java.awt.image.BufferedImage; +import java.awt.image.VolatileImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +public class AcceleratedXORModeTest { + public static void main(String argv[]) { + String fileName = argv.length > 0 ? argv[0] : null; + new AcceleratedXORModeTest(fileName).test(); + } + + static final Color backColor = Color.red; + static final Color color1 = Color.green; + static final Color color2 = Color.yellow; + static final Color xorColor1 = Color.blue; + static final Color xorColor2 = Color.white; + + static final int width = 700, height = 300; + + VolatileImage vImg = null; + String fileName; + + public AcceleratedXORModeTest(String fileName) { + this.fileName = fileName; + } + + void draw(Graphics2D g) { + g.setColor(backColor); + g.fillRect(0, 0, width, height); + g.setXORMode(xorColor1); + drawPattern(g, 100); + g.setXORMode(xorColor2); + drawPattern(g, 400); + g.dispose(); + } + + void test(BufferedImage bi) { + comparePattern(bi, 150, xorColor1.getRGB()); + comparePattern(bi, 450, xorColor2.getRGB()); + } + + void comparePattern(BufferedImage bi, int startX, int xorColor) { + int[] expectedColors = { + backColor.getRGB() ^ color1.getRGB() ^ xorColor, + backColor.getRGB() ^ color1.getRGB() ^ xorColor ^ + color2.getRGB() ^ xorColor, + backColor.getRGB() ^ color2.getRGB() ^ xorColor + }; + for (int i = 0; i < 3; i++) { + int x = startX + 100 * i; + int rgb = bi.getRGB(x, 150); + if (rgb != expectedColors[i]) { + String msg = "Colors mismatch: x = " + x + + ", got " + new Color(rgb) + ", expected " + + new Color(expectedColors[i]); + System.err.println(msg); + write(bi); + throw new RuntimeException("FAILED: " + msg); + } + } + } + + void drawPattern(Graphics2D g, int x) { + g.setColor(color1); + g.fillRect(x, 0, 200, 300); + g.setColor(color2); + g.fillRect(x+100, 0, 200, 300); + } + + GraphicsConfiguration getDefaultGC() { + return GraphicsEnvironment.getLocalGraphicsEnvironment(). + getDefaultScreenDevice().getDefaultConfiguration(); + } + + void createVImg() { + if (vImg != null) { + vImg.flush(); + vImg = null; + } + vImg = getDefaultGC().createCompatibleVolatileImage(width, height); + } + + void write(BufferedImage bi) { + if (fileName != null) { + try { + ImageIO.write(bi, "png", new File(fileName)); + } catch (IOException e) { + System.err.println("Can't write image file " + fileName); + } + } + } + + void test() { + createVImg(); + do { + int valCode = vImg.validate(getDefaultGC()); + if (valCode == VolatileImage.IMAGE_INCOMPATIBLE) { + createVImg(); + } + Graphics2D g = vImg.createGraphics(); + draw(g); + BufferedImage bi = vImg.getSnapshot(); + test(bi); + write(bi); + } while (vImg.contentsLost()); + } +}