提交 35d733cd 编写于 作者: P prr

8220186: Improve use of font temporary files

Reviewed-by: serb, psadhukhan, mschoene, rhalade
上级 9cb9fc47
...@@ -171,7 +171,7 @@ public abstract class FileFont extends PhysicalFont { ...@@ -171,7 +171,7 @@ public abstract class FileFont extends PhysicalFont {
} }
} }
if (scaler != null) { if (scaler != null) {
scaler.dispose(); scaler.disposeScaler();
} }
scaler = FontScaler.getNullScaler(); scaler = FontScaler.getNullScaler();
} }
......
...@@ -198,6 +198,12 @@ public abstract class FontScaler implements DisposerRecord { ...@@ -198,6 +198,12 @@ public abstract class FontScaler implements DisposerRecord {
scaler context objects! */ scaler context objects! */
public void dispose() {} public void dispose() {}
/**
* Used when the native resources held by the scaler need
* to be released before the 2D disposer runs.
*/
public void disposeScaler() {}
/* At the moment these 3 methods are needed for Type1 fonts only. /* At the moment these 3 methods are needed for Type1 fonts only.
* For Truetype fonts we extract required info outside of scaler * For Truetype fonts we extract required info outside of scaler
* on java layer. * on java layer.
......
...@@ -167,6 +167,9 @@ class FreetypeFontScaler extends FontScaler { ...@@ -167,6 +167,9 @@ class FreetypeFontScaler extends FontScaler {
return getLayoutTableCacheNative(nativeScaler); return getLayoutTableCacheNative(nativeScaler);
} }
/* This method should not be called directly, in case
* it is being invoked from a thread with a native context.
*/
public synchronized void dispose() { public synchronized void dispose() {
if (nativeScaler != 0L) { if (nativeScaler != 0L) {
disposeNativeScaler(font.get(), nativeScaler); disposeNativeScaler(font.get(), nativeScaler);
...@@ -174,6 +177,21 @@ class FreetypeFontScaler extends FontScaler { ...@@ -174,6 +177,21 @@ class FreetypeFontScaler extends FontScaler {
} }
} }
public synchronized void disposeScaler() {
if (nativeScaler != 0L) {
/*
* The current thread may be calling this method from the context
* of a JNI up-call. It will hold the native lock from the
* original down-call so can directly enter dispose and free
* the resources. So we need to schedule the disposal to happen
* only once we've returned from native. So by running the dispose
* on another thread which does nothing except that disposal we
* are sure that this is safe.
*/
new Thread(null, () -> dispose(), "free scaler", 0).start();
}
}
synchronized int getNumGlyphs() throws FontScalerException { synchronized int getNumGlyphs() throws FontScalerException {
if (nativeScaler != 0L) { if (nativeScaler != 0L) {
return getNumGlyphsNative(nativeScaler); return getNumGlyphsNative(nativeScaler);
...@@ -210,7 +228,7 @@ class FreetypeFontScaler extends FontScaler { ...@@ -210,7 +228,7 @@ class FreetypeFontScaler extends FontScaler {
return getUnitsPerEMNative(nativeScaler); return getUnitsPerEMNative(nativeScaler);
} }
long createScalerContext(double[] matrix, synchronized long createScalerContext(double[] matrix,
int aa, int fm, float boldness, float italic, int aa, int fm, float boldness, float italic,
boolean disableHinting) { boolean disableHinting) {
if (nativeScaler != 0L) { if (nativeScaler != 0L) {
...@@ -240,7 +258,7 @@ class FreetypeFontScaler extends FontScaler { ...@@ -240,7 +258,7 @@ class FreetypeFontScaler extends FontScaler {
private native GeneralPath getGlyphVectorOutlineNative(Font2D font, private native GeneralPath getGlyphVectorOutlineNative(Font2D font,
long pScalerContext, long pScaler, long pScalerContext, long pScaler,
int[] glyphs, int numGlyphs, float x, float y); int[] glyphs, int numGlyphs, float x, float y);
native Point2D.Float getGlyphPointNative(Font2D font, private native Point2D.Float getGlyphPointNative(Font2D font,
long pScalerContext, long pScaler, int glyphCode, int ptNumber); long pScalerContext, long pScaler, int glyphCode, int ptNumber);
private native long getLayoutTableCacheNative(long pScaler); private native long getLayoutTableCacheNative(long pScaler);
...@@ -253,7 +271,7 @@ class FreetypeFontScaler extends FontScaler { ...@@ -253,7 +271,7 @@ class FreetypeFontScaler extends FontScaler {
private native long getUnitsPerEMNative(long pScaler); private native long getUnitsPerEMNative(long pScaler);
native long createScalerContextNative(long pScaler, double[] matrix, private native long createScalerContextNative(long pScaler, double[] matrix,
int aa, int fm, float boldness, float italic); int aa, int fm, float boldness, float italic);
/* Freetype scaler context does not contain any pointers that /* Freetype scaler context does not contain any pointers that
......
...@@ -154,7 +154,31 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream, ...@@ -154,7 +154,31 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
jobject bBuffer; jobject bBuffer;
int bread = 0; int bread = 0;
if (numBytes == 0) return 0; /* A call with numBytes == 0 is a seek. It should return 0 if the
* seek position is within the file and non-zero otherwise.
* For all other cases, ie numBytes !=0, return the number of bytes
* actually read. This applies to truncated reads and also failed reads.
*/
if (numBytes == 0) {
if (offset >= scalerInfo->fileSize) {
return -1;
} else {
return 0;
}
}
if (offset + numBytes < offset) {
return 0; // ft should not do this, but just in case.
}
if (offset >= scalerInfo->fileSize) {
return 0;
}
if (offset + numBytes > scalerInfo->fileSize) {
numBytes = scalerInfo->fileSize - offset;
}
/* Large reads will bypass the cache and data copying */ /* Large reads will bypass the cache and data copying */
if (numBytes > FILEDATACACHESIZE) { if (numBytes > FILEDATACACHESIZE) {
...@@ -164,7 +188,11 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream, ...@@ -164,7 +188,11 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
scalerInfo->font2D, scalerInfo->font2D,
sunFontIDs.ttReadBlockMID, sunFontIDs.ttReadBlockMID,
bBuffer, offset, numBytes); bBuffer, offset, numBytes);
return bread; if (bread < 0) {
return 0;
} else {
return bread;
}
} else { } else {
/* We probably hit bug bug 4845371. For reasons that /* We probably hit bug bug 4845371. For reasons that
* are currently unclear, the call stacks after the initial * are currently unclear, the call stacks after the initial
...@@ -179,9 +207,18 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream, ...@@ -179,9 +207,18 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
(*env)->CallObjectMethod(env, scalerInfo->font2D, (*env)->CallObjectMethod(env, scalerInfo->font2D,
sunFontIDs.ttReadBytesMID, sunFontIDs.ttReadBytesMID,
offset, numBytes); offset, numBytes);
(*env)->GetByteArrayRegion(env, byteArray, /* If there's an OutofMemoryError then byteArray will be null */
0, numBytes, (jbyte*)destBuffer); if (byteArray == NULL) {
return numBytes; return 0;
} else {
jsize len = (*env)->GetArrayLength(env, byteArray);
if (len < numBytes) {
numBytes = len; // don't get more bytes than there are ..
}
(*env)->GetByteArrayRegion(env, byteArray,
0, numBytes, (jbyte*)destBuffer);
return numBytes;
}
} }
} /* Do we have a cache hit? */ } /* Do we have a cache hit? */
else if (scalerInfo->fontDataOffset <= offset && else if (scalerInfo->fontDataOffset <= offset &&
...@@ -203,6 +240,11 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream, ...@@ -203,6 +240,11 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
sunFontIDs.ttReadBlockMID, sunFontIDs.ttReadBlockMID,
bBuffer, offset, bBuffer, offset,
scalerInfo->fontDataLength); scalerInfo->fontDataLength);
if (bread <= 0) {
return 0;
} else if (bread < numBytes) {
numBytes = bread;
}
memcpy(destBuffer, scalerInfo->fontData, numBytes); memcpy(destBuffer, scalerInfo->fontData, numBytes);
return numBytes; return numBytes;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册