Mercurial > hg > release > icedtea7-forest-2.1 > jdk
changeset 1983:fb53cb501b9e
Merge
author | lana |
---|---|
date | Wed, 18 Nov 2009 17:16:27 -0800 |
parents | 941b3fd6c22b (current diff) ba01efbf7c70 (diff) |
children | dfcdf8ade255 |
files | |
diffstat | 23 files changed, 298 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/javax/print/attribute/standard/PrinterStateReasons.java Wed Nov 18 17:16:27 2009 -0800 @@ -65,7 +65,7 @@ * PrinterStateReason PrinterStateReason} objects to an existing * PrinterStateReasons object and remove them again. However, like class * {@link java.util.HashMap java.util.HashMap}, class PrinterStateReasons is - * bot multiple thread safe. If a PrinterStateReasons object will be used by + * not multiple thread safe. If a PrinterStateReasons object will be used by * multiple threads, be sure to synchronize its operations (e.g., using a * synchronized map view obtained from class {@link java.util.Collections * java.util.Collections}).
--- a/src/share/classes/sun/font/Font2D.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/font/Font2D.java Wed Nov 18 17:16:27 2009 -0800 @@ -320,21 +320,6 @@ lastFontStrike = new SoftReference(strike); StrikeCache.refStrike(strike); return strike; - } else { - /* We have found a cleared reference that has not yet - * been removed by the disposer. - * If we make this reference unreachable by removing it - * from the map,or overwriting it with a new reference to - * a new strike, then it is possible it may never be - * enqueued for disposal. That is the implication of - * the docs for java.lang.ref. So on finding a cleared - * reference, we need to dispose the native resources, - * if they haven't already been freed. - * The reference object needs to have a reference to - * the disposer instance for this to occur. - */ - ((StrikeCache.DisposableStrike)strikeRef) - .getDisposer().dispose(); } } /* When we create a new FontStrike instance, we *must*
--- a/src/share/classes/sun/font/FontDesignMetrics.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/font/FontDesignMetrics.java Wed Nov 18 17:16:27 2009 -0800 @@ -171,7 +171,7 @@ * out we can clear the keys from the table. */ private static class KeyReference extends SoftReference - implements DisposerRecord { + implements DisposerRecord, Disposer.PollDisposable { static ReferenceQueue queue = Disposer.getQueue();
--- a/src/share/classes/sun/font/FontStrikeDisposer.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/font/FontStrikeDisposer.java Wed Nov 18 17:16:27 2009 -0800 @@ -25,6 +25,7 @@ package sun.font; +import sun.java2d.Disposer; import sun.java2d.DisposerRecord; /* @@ -49,7 +50,8 @@ * entries would be removed much more promptly than we need. */ -class FontStrikeDisposer implements DisposerRecord { +class FontStrikeDisposer + implements DisposerRecord, Disposer.PollDisposable { Font2D font2D; FontStrikeDesc desc;
--- a/src/share/classes/sun/font/StrikeCache.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/font/StrikeCache.java Wed Nov 18 17:16:27 2009 -0800 @@ -254,9 +254,20 @@ // because they may be accessed on that thread at the time of the // disposal (for example, when the accel. cache is invalidated) - // REMIND: this look a bit heavyweight, but should be ok - // because strike disposal is a relatively infrequent operation, - // more worrisome is the necessity of getting a GC here. + // Whilst this is a bit heavyweight, in most applications + // strike disposal is a relatively infrequent operation, so it + // doesn't matter. But in some tests that use vast numbers + // of strikes, the switching back and forth is measurable. + // So the "pollRemove" call is added to batch up the work. + // If we are polling we know we've already been called back + // and can directly dispose the record. + // Also worrisome is the necessity of getting a GC here. + + if (Disposer.pollingQueue) { + doDispose(disposer); + return; + } + RenderQueue rq = null; GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); @@ -277,6 +288,7 @@ rq.flushAndInvokeNow(new Runnable() { public void run() { doDispose(disposer); + Disposer.pollRemove(); } }); } finally {
--- a/src/share/classes/sun/java2d/Disposer.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/java2d/Disposer.java Wed Nov 18 17:16:27 2009 -0800 @@ -29,6 +29,7 @@ import java.lang.ref.ReferenceQueue; import java.lang.ref.PhantomReference; import java.lang.ref.WeakReference; +import java.util.ArrayList; import java.util.Hashtable; /** @@ -146,6 +147,7 @@ rec.dispose(); obj = null; rec = null; + clearDeferredRecords(); } catch (Exception e) { System.out.println("Exception while removing reference: " + e); e.printStackTrace(); @@ -153,6 +155,85 @@ } } + /* + * This is a marker interface that, if implemented, means it + * doesn't acquire any special locks, and is safe to + * be disposed in the poll loop on whatever thread + * which happens to be the Toolkit thread, is in use. + */ + public static interface PollDisposable { + }; + + private static ArrayList<DisposerRecord> deferredRecords = null; + + private static void clearDeferredRecords() { + if (deferredRecords == null || deferredRecords.isEmpty()) { + return; + } + for (int i=0;i<deferredRecords.size(); i++) { + try { + DisposerRecord rec = deferredRecords.get(i); + rec.dispose(); + } catch (Exception e) { + System.out.println("Exception while disposing deferred rec."); + e.printStackTrace(); + } + } + deferredRecords.clear(); + } + + /* + * Set to indicate the queue is presently being polled. + */ + public static volatile boolean pollingQueue = false; + + /* + * The pollRemove() method is called back from a dispose method + * that is running on the toolkit thread and wants to + * dispose any pending refs that are safe to be disposed + * on that thread. + */ + public static void pollRemove() { + + /* This should never be called recursively, so this check + * is just a safeguard against the unexpected. + */ + if (pollingQueue) { + return; + } + Object obj; + pollingQueue = true; + int freed = 0; + int deferred = 0; + try { + while ((obj = queue.poll()) != null + && freed < 10000 && deferred < 100) { + freed++; + ((Reference)obj).clear(); + DisposerRecord rec = (DisposerRecord)records.remove(obj); + if (rec instanceof PollDisposable) { + rec.dispose(); + obj = null; + rec = null; + } else { + if (rec == null) { // shouldn't happen, but just in case. + continue; + } + deferred++; + if (deferredRecords == null) { + deferredRecords = new ArrayList<DisposerRecord>(5); + } + deferredRecords.add(rec); + } + } + } catch (Exception e) { + System.out.println("Exception while removing reference: " + e); + e.printStackTrace(); + } finally { + pollingQueue = false; + } + } + private static native void initIDs(); /*
--- a/src/share/classes/sun/java2d/SunGraphics2D.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/java2d/SunGraphics2D.java Wed Nov 18 17:16:27 2009 -0800 @@ -257,7 +257,6 @@ font = defaultFont; } - loops = sd.getRenderLoops(this); setDevClip(sd.getBounds()); invalidatePipe(); } @@ -367,6 +366,7 @@ shapepipe = invalidpipe; textpipe = invalidpipe; imagepipe = invalidpipe; + loops = null; } public void validatePipe() {
--- a/src/share/classes/sun/java2d/SurfaceData.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/java2d/SurfaceData.java Wed Nov 18 17:16:27 2009 -0800 @@ -69,6 +69,7 @@ import sun.java2d.pipe.DrawImage; import sun.awt.SunHints; import sun.awt.image.SurfaceManager; +import sun.java2d.pipe.LoopBasedPipe; /** * This class provides various pieces of information relevant to a @@ -506,7 +507,6 @@ sg2d.textpipe = solidTextRenderer; } sg2d.shapepipe = colorPrimitives; - sg2d.loops = getRenderLoops(sg2d); // assert(sg2d.surfaceData == this); } } else if (sg2d.compositeState == sg2d.COMP_CUSTOM) { @@ -603,8 +603,17 @@ sg2d.textpipe = getTextPipe(sg2d, false /* AA==OFF */); sg2d.shapepipe = colorPrimitives; + // assert(sg2d.surfaceData == this); + } + + // check for loops + if (sg2d.textpipe instanceof LoopBasedPipe || + sg2d.shapepipe instanceof LoopBasedPipe || + sg2d.fillpipe instanceof LoopBasedPipe || + sg2d.drawpipe instanceof LoopBasedPipe || + sg2d.imagepipe instanceof LoopBasedPipe) + { sg2d.loops = getRenderLoops(sg2d); - // assert(sg2d.surfaceData == this); } }
--- a/src/share/classes/sun/java2d/pipe/AATextRenderer.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/java2d/pipe/AATextRenderer.java Wed Nov 18 17:16:27 2009 -0800 @@ -34,8 +34,9 @@ * a solid source colour to an opaque destination. */ -public class AATextRenderer extends GlyphListLoopPipe { - +public class AATextRenderer extends GlyphListLoopPipe + implements LoopBasedPipe +{ protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) { sg2d.loops.drawGlyphListAALoop.DrawGlyphListAA(sg2d, sg2d.surfaceData, gl);
--- a/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/java2d/pipe/GlyphListLoopPipe.java Wed Nov 18 17:16:27 2009 -0800 @@ -36,8 +36,9 @@ * the installed loop may not match the glyphvector. */ -public abstract class GlyphListLoopPipe extends GlyphListPipe { - +public abstract class GlyphListLoopPipe extends GlyphListPipe + implements LoopBasedPipe +{ protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl, int aaHint) { switch (aaHint) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/java2d/pipe/LoopBasedPipe.java Wed Nov 18 17:16:27 2009 -0800 @@ -0,0 +1,37 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.pipe; + +/** + * This is a marker interface used by Pipes that need RenderLoops. + * RenderLoops are validated in SurfaceData when a pipe is recognised to + * implement this interface. + * + * @author Mario Torre <neugens@aicas.com> + */ +public interface LoopBasedPipe { + +}
--- a/src/share/classes/sun/java2d/pipe/LoopPipe.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/java2d/pipe/LoopPipe.java Wed Nov 18 17:16:27 2009 -0800 @@ -46,7 +46,8 @@ public class LoopPipe implements PixelDrawPipe, PixelFillPipe, - ShapeDrawPipe + ShapeDrawPipe, + LoopBasedPipe { final static RenderingEngine RenderEngine = RenderingEngine.getInstance();
--- a/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/java2d/pipe/SolidTextRenderer.java Wed Nov 18 17:16:27 2009 -0800 @@ -35,8 +35,9 @@ * a solid source colour to an opaque destination. */ -public class SolidTextRenderer extends GlyphListLoopPipe { - +public class SolidTextRenderer extends GlyphListLoopPipe + implements LoopBasedPipe +{ protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl) { sg2d.loops.drawGlyphListLoop.DrawGlyphList(sg2d, sg2d.surfaceData, gl); }
--- a/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/java2d/pipe/SpanShapeRenderer.java Wed Nov 18 17:16:27 2009 -0800 @@ -65,7 +65,9 @@ } } - public static class Simple extends SpanShapeRenderer { + public static class Simple extends SpanShapeRenderer + implements LoopBasedPipe + { public Object startSequence(SunGraphics2D sg, Shape s, Rectangle devR, int[] bbox) { return sg;
--- a/src/share/classes/sun/java2d/pisces/Renderer.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/classes/sun/java2d/pisces/Renderer.java Wed Nov 18 17:16:27 2009 -0800 @@ -775,10 +775,12 @@ // Free sorting arrays if larger than maximum size private void crossingListFinished() { - if (crossings.length > DEFAULT_CROSSINGS_SIZE) { + if (crossings != null && crossings.length > DEFAULT_CROSSINGS_SIZE) { crossings = new int[DEFAULT_CROSSINGS_SIZE]; } - if (crossingIndices.length > DEFAULT_INDICES_SIZE) { + if (crossingIndices != null && + crossingIndices.length > DEFAULT_INDICES_SIZE) + { crossingIndices = new int[DEFAULT_INDICES_SIZE]; } }
--- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c Wed Nov 18 17:16:27 2009 -0800 @@ -1437,6 +1437,7 @@ JNU_ThrowByName( env, "java/lang/OutOfMemoryError", "Initializing Reader"); + free(cinfo); return 0; } @@ -1473,6 +1474,7 @@ JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Initializing Reader"); + imageio_dispose((j_common_ptr)cinfo); return 0; } cinfo->src->bytes_in_buffer = 0; @@ -1489,6 +1491,7 @@ JNU_ThrowByName( env, "java/lang/OutOfMemoryError", "Initializing Reader"); + imageio_dispose((j_common_ptr)cinfo); return 0; } return (jlong) ret; @@ -2420,8 +2423,7 @@ JNU_ThrowByName( env, "java/lang/OutOfMemoryError", "Initializing Writer"); - free(cinfo); - free(jerr); + imageio_dispose((j_common_ptr)cinfo); return 0; } @@ -2439,8 +2441,7 @@ JNU_ThrowByName( env, "java/lang/OutOfMemoryError", "Initializing Writer"); - free(cinfo); - free(jerr); + imageio_dispose((j_common_ptr)cinfo); return 0; } return (jlong) ret;
--- a/src/share/native/sun/awt/medialib/awt_ImagingLib.c Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/native/sun/awt/medialib/awt_ImagingLib.c Wed Nov 18 17:16:27 2009 -0800 @@ -960,21 +960,15 @@ mlib_filter filter; unsigned int *dP; - if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) { - JNU_ThrowOutOfMemoryError(env, "Out of memory"); - return -1; - } - - if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) { - JNU_ThrowOutOfMemoryError(env, "Out of memory"); - free(srcRasterP); - return -1; - } - /* This function requires a lot of local refs ??? Is 64 enough ??? */ if ((*env)->EnsureLocalCapacity(env, 64) < 0) return 0; + if (s_nomlib) return 0; + if (s_timeIt) { + (*start_timer)(3600); + } + switch(interpType) { case java_awt_image_AffineTransformOp_TYPE_BILINEAR: filter = MLIB_BILINEAR; @@ -990,9 +984,15 @@ return -1; } - if (s_nomlib) return 0; - if (s_timeIt) { - (*start_timer)(3600); + if ((srcRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) { + JNU_ThrowOutOfMemoryError(env, "Out of memory"); + return -1; + } + + if ((dstRasterP = (RasterS_t *) calloc(1, sizeof(RasterS_t))) == NULL) { + JNU_ThrowOutOfMemoryError(env, "Out of memory"); + free(srcRasterP); + return -1; } if ((*env)->GetArrayLength(env, jmatrix) < 6) { @@ -1215,6 +1215,9 @@ } if (tbl == NULL || table == NULL || jtable == NULL) { + if (tbl != NULL) free(tbl); + if (table != NULL) free(table); + if (jtable != NULL) free(jtable); awt_freeParsedImage(srcImageP, TRUE); awt_freeParsedImage(dstImageP, TRUE); JNU_ThrowNullPointerException(env, "NULL LUT"); @@ -1224,6 +1227,11 @@ for (i=0; i < jlen; i++) { jtable[i] = (*env)->GetObjectArrayElement(env, jtableArrays, i); if (jtable[i] == NULL) { + free(tbl); + free(table); + free(jtable); + awt_freeParsedImage(srcImageP, TRUE); + awt_freeParsedImage(dstImageP, TRUE); return 0; } } @@ -1232,6 +1240,9 @@ FALSE, &hint); if (nbands < 1) { /* Can't handle any custom images */ + free(tbl); + free(table); + free(jtable); awt_freeParsedImage(srcImageP, TRUE); awt_freeParsedImage(dstImageP, TRUE); return 0; @@ -1240,12 +1251,18 @@ /* Allocate the arrays */ if (allocateArray(env, srcImageP, &src, &sdata, TRUE, FALSE, FALSE) < 0) { /* Must be some problem */ + free(tbl); + free(table); + free(jtable); awt_freeParsedImage(srcImageP, TRUE); awt_freeParsedImage(dstImageP, TRUE); return 0; } if (allocateArray(env, dstImageP, &dst, &ddata, FALSE, FALSE, FALSE) < 0) { /* Must be some problem */ + free(tbl); + free(table); + free(jtable); freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL); awt_freeParsedImage(srcImageP, TRUE); awt_freeParsedImage(dstImageP, TRUE); @@ -1284,6 +1301,9 @@ (jbyte *) table[j], JNI_ABORT); } + free(tbl); + free(table); + free(jtable); freeArray(env, srcImageP, src, sdata, NULL, NULL, NULL); awt_freeParsedImage(srcImageP, TRUE); awt_freeParsedImage(dstImageP, TRUE); @@ -1413,12 +1433,15 @@ /* Parse the source raster - reject custom images */ if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) { + free(srcRasterP); + free(dstRasterP); return 0; } /* Parse the destination image - reject custom images */ if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) { awt_freeParsedRaster(srcRasterP, TRUE); + free(dstRasterP); return 0; }
--- a/src/share/native/sun/font/freetypeScaler.c Thu Nov 12 15:35:52 2009 -0800 +++ b/src/share/native/sun/font/freetypeScaler.c Wed Nov 18 17:16:27 2009 -0800 @@ -102,9 +102,21 @@ } static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) { + void *stream; + if (scalerInfo == NULL) return; + //apparently Done_Face will only close the stream + // but will not relase the memory of stream structure. + // We need to free it explicitly to avoid leak. + //Direct access to the stream field might be not ideal solution as + // it is considred to be "private". + //Alternatively we could have stored pointer to the structure + // in the scalerInfo but this will increase size of the structure + // for no good reason + stream = scalerInfo->face->stream; + FT_Done_Face(scalerInfo->face); FT_Done_FreeType(scalerInfo->library); @@ -116,6 +128,10 @@ free(scalerInfo->fontData); } + if (stream != NULL) { + free(stream); + } + free(scalerInfo); }
--- a/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/solaris/classes/sun/java2d/x11/X11SurfaceData.java Wed Nov 18 17:16:27 2009 -0800 @@ -388,7 +388,10 @@ // if a GlyphVector overrides the AA setting. // We use getRenderLoops() rather than setting solidloops // directly so that we get the appropriate loops in XOR mode. - sg2d.loops = getRenderLoops(sg2d); + if (sg2d.loops == null) { + // assert(some pipe will always be a LoopBasedPipe) + sg2d.loops = getRenderLoops(sg2d); + } } else { super.validatePipe(sg2d); }
--- a/src/solaris/native/sun/awt/awt_GraphicsEnv.h Thu Nov 12 15:35:52 2009 -0800 +++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.h Wed Nov 18 17:16:27 2009 -0800 @@ -42,6 +42,10 @@ #include <sys/ipc.h> #include <sys/shm.h> #include <X11/extensions/XShm.h> +#ifndef X_ShmAttach +#include <X11/Xmd.h> +#include <X11/extensions/shmproto.h> +#endif extern int XShmQueryExtension();
--- a/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java Thu Nov 12 15:35:52 2009 -0800 +++ b/src/windows/classes/sun/java2d/windows/GDIWindowSurfaceData.java Wed Nov 18 17:16:27 2009 -0800 @@ -210,7 +210,10 @@ // if a GlyphVector overrides the AA setting. // We use getRenderLoops() rather than setting solidloops // directly so that we get the appropriate loops in XOR mode. - sg2d.loops = getRenderLoops(sg2d); + if (sg2d.loops == null) { + // assert(some pipe will always be a LoopBasedPipe) + sg2d.loops = getRenderLoops(sg2d); + } } else { super.validatePipe(sg2d); }
--- a/src/windows/native/sun/windows/awt_PrintControl.cpp Thu Nov 12 15:35:52 2009 -0800 +++ b/src/windows/native/sun/windows/awt_PrintControl.cpp Wed Nov 18 17:16:27 2009 -0800 @@ -687,7 +687,7 @@ // Now, set-up the struct for the real calls to ::PrintDlg and ::CreateDC pd.hwndOwner = hwndOwner; - pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC; + pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE; pd.lpfnPrintHook = (LPPRINTHOOKPROC)PrintDlgHook; if (env->CallBooleanMethod(printCtrl, AwtPrintControl::getCollateID)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/java2d/pisces/Renderer/TestNPE.java Wed Nov 18 17:16:27 2009 -0800 @@ -0,0 +1,59 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6887494 + * + * @summary Verifies that no NullPointerException is thrown in Pisces Renderer + * under certain circumstances. + * + * @run main TestNPE + */ + +import java.awt.*; +import java.awt.geom.*; +import java.awt.image.BufferedImage; + +public class TestNPE { + + private static void paint(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setClip(0, 0, 0, 0); + g2d.setTransform( + new AffineTransform(4.0f, 0.0f, 0.0f, 4.0f, -1248.0f, -744.0f)); + g2d.draw(new Line2D.Float(131.21428571428572f, 33.0f, + 131.21428571428572f, 201.0f)); + } + + public static void main(String[] args) { + BufferedImage im = new BufferedImage(100, 100, + BufferedImage.TYPE_INT_ARGB); + + // Trigger exception in main thread. + Graphics g = im.getGraphics(); + paint(g); + } +}