Merge
This commit is contained in:
commit
f3baefc4fb
@ -65,7 +65,7 @@ import javax.print.attribute.PrintServiceAttribute;
|
||||
* 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}).
|
||||
|
@ -320,21 +320,6 @@ public abstract class Font2D {
|
||||
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*
|
||||
|
@ -171,7 +171,7 @@ public final class FontDesignMetrics extends FontMetrics {
|
||||
* 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();
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
package sun.font;
|
||||
|
||||
import sun.java2d.Disposer;
|
||||
import sun.java2d.DisposerRecord;
|
||||
|
||||
/*
|
||||
@ -49,7 +50,8 @@ import sun.java2d.DisposerRecord;
|
||||
* entries would be removed much more promptly than we need.
|
||||
*/
|
||||
|
||||
class FontStrikeDisposer implements DisposerRecord {
|
||||
class FontStrikeDisposer
|
||||
implements DisposerRecord, Disposer.PollDisposable {
|
||||
|
||||
Font2D font2D;
|
||||
FontStrikeDesc desc;
|
||||
|
@ -254,9 +254,20 @@ public final class StrikeCache {
|
||||
// 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 @@ public final class StrikeCache {
|
||||
rq.flushAndInvokeNow(new Runnable() {
|
||||
public void run() {
|
||||
doDispose(disposer);
|
||||
Disposer.pollRemove();
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
|
@ -29,6 +29,7 @@ import java.lang.ref.Reference;
|
||||
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 @@ public class Disposer implements Runnable {
|
||||
rec.dispose();
|
||||
obj = null;
|
||||
rec = null;
|
||||
clearDeferredRecords();
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception while removing reference: " + e);
|
||||
e.printStackTrace();
|
||||
@ -153,6 +155,85 @@ public class Disposer implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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();
|
||||
|
||||
/*
|
||||
|
@ -257,7 +257,6 @@ public final class SunGraphics2D
|
||||
font = defaultFont;
|
||||
}
|
||||
|
||||
loops = sd.getRenderLoops(this);
|
||||
setDevClip(sd.getBounds());
|
||||
invalidatePipe();
|
||||
}
|
||||
@ -367,6 +366,7 @@ public final class SunGraphics2D
|
||||
shapepipe = invalidpipe;
|
||||
textpipe = invalidpipe;
|
||||
imagepipe = invalidpipe;
|
||||
loops = null;
|
||||
}
|
||||
|
||||
public void validatePipe() {
|
||||
|
@ -69,6 +69,7 @@ import sun.java2d.pipe.DrawImagePipe;
|
||||
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 @@ public abstract class SurfaceData
|
||||
sg2d.textpipe = solidTextRenderer;
|
||||
}
|
||||
sg2d.shapepipe = colorPrimitives;
|
||||
sg2d.loops = getRenderLoops(sg2d);
|
||||
// assert(sg2d.surfaceData == this);
|
||||
}
|
||||
} else if (sg2d.compositeState == sg2d.COMP_CUSTOM) {
|
||||
@ -603,9 +603,18 @@ public abstract class SurfaceData
|
||||
|
||||
sg2d.textpipe = getTextPipe(sg2d, false /* AA==OFF */);
|
||||
sg2d.shapepipe = colorPrimitives;
|
||||
sg2d.loops = getRenderLoops(sg2d);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the text pipe to be used based on the graphics AA hint setting,
|
||||
|
@ -34,8 +34,9 @@ import sun.font.GlyphList;
|
||||
* 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);
|
||||
|
@ -36,8 +36,9 @@ import sun.font.GlyphList;
|
||||
* 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) {
|
||||
|
37
jdk/src/share/classes/sun/java2d/pipe/LoopBasedPipe.java
Normal file
37
jdk/src/share/classes/sun/java2d/pipe/LoopBasedPipe.java
Normal file
@ -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 {
|
||||
|
||||
}
|
@ -46,7 +46,8 @@ import sun.awt.SunHints;
|
||||
public class LoopPipe
|
||||
implements PixelDrawPipe,
|
||||
PixelFillPipe,
|
||||
ShapeDrawPipe
|
||||
ShapeDrawPipe,
|
||||
LoopBasedPipe
|
||||
{
|
||||
final static RenderingEngine RenderEngine = RenderingEngine.getInstance();
|
||||
|
||||
|
@ -35,8 +35,9 @@ import sun.font.GlyphList;
|
||||
* 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);
|
||||
}
|
||||
|
@ -65,7 +65,9 @@ public abstract class SpanShapeRenderer implements ShapeDrawPipe {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -775,10 +775,12 @@ public class Renderer extends LineSink {
|
||||
|
||||
// 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];
|
||||
}
|
||||
}
|
||||
|
@ -1437,6 +1437,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader
|
||||
JNU_ThrowByName( env,
|
||||
"java/lang/OutOfMemoryError",
|
||||
"Initializing Reader");
|
||||
free(cinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1473,6 +1474,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader
|
||||
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 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initJPEGImageReader
|
||||
JNU_ThrowByName( env,
|
||||
"java/lang/OutOfMemoryError",
|
||||
"Initializing Reader");
|
||||
imageio_dispose((j_common_ptr)cinfo);
|
||||
return 0;
|
||||
}
|
||||
return (jlong) ret;
|
||||
@ -2420,8 +2423,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initJPEGImageWriter
|
||||
JNU_ThrowByName( env,
|
||||
"java/lang/OutOfMemoryError",
|
||||
"Initializing Writer");
|
||||
free(cinfo);
|
||||
free(jerr);
|
||||
imageio_dispose((j_common_ptr)cinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2439,8 +2441,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initJPEGImageWriter
|
||||
JNU_ThrowByName( env,
|
||||
"java/lang/OutOfMemoryError",
|
||||
"Initializing Writer");
|
||||
free(cinfo);
|
||||
free(jerr);
|
||||
imageio_dispose((j_common_ptr)cinfo);
|
||||
return 0;
|
||||
}
|
||||
return (jlong) ret;
|
||||
|
@ -960,21 +960,15 @@ Java_sun_awt_image_ImagingLib_transformRaster(JNIEnv *env, jobject this,
|
||||
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 @@ Java_sun_awt_image_ImagingLib_transformRaster(JNIEnv *env, jobject this,
|
||||
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 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this,
|
||||
}
|
||||
|
||||
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 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this,
|
||||
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 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this,
|
||||
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 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this,
|
||||
/* 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 @@ Java_sun_awt_image_ImagingLib_lookupByteBI(JNIEnv *env, jobject this,
|
||||
(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 @@ Java_sun_awt_image_ImagingLib_lookupByteRaster(JNIEnv *env,
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
@ -102,9 +102,21 @@ Java_sun_font_FreetypeFontScaler_initIDs(
|
||||
}
|
||||
|
||||
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 @@ static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) {
|
||||
free(scalerInfo->fontData);
|
||||
}
|
||||
|
||||
if (stream != NULL) {
|
||||
free(stream);
|
||||
}
|
||||
|
||||
free(scalerInfo);
|
||||
}
|
||||
|
||||
|
@ -388,7 +388,10 @@ public abstract class X11SurfaceData extends SurfaceData {
|
||||
// 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.
|
||||
if (sg2d.loops == null) {
|
||||
// assert(some pipe will always be a LoopBasedPipe)
|
||||
sg2d.loops = getRenderLoops(sg2d);
|
||||
}
|
||||
} else {
|
||||
super.validatePipe(sg2d);
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -210,7 +210,10 @@ public class GDIWindowSurfaceData extends SurfaceData {
|
||||
// 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.
|
||||
if (sg2d.loops == null) {
|
||||
// assert(some pipe will always be a LoopBasedPipe)
|
||||
sg2d.loops = getRenderLoops(sg2d);
|
||||
}
|
||||
} else {
|
||||
super.validatePipe(sg2d);
|
||||
}
|
||||
|
@ -687,7 +687,7 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env,
|
||||
// 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)) {
|
||||
|
59
jdk/test/sun/java2d/pisces/Renderer/TestNPE.java
Normal file
59
jdk/test/sun/java2d/pisces/Renderer/TestNPE.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user