提交 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 {
}
}
if (scaler != null) {
scaler.dispose();
scaler.disposeScaler();
}
scaler = FontScaler.getNullScaler();
}
......
......@@ -198,6 +198,12 @@ public abstract class FontScaler implements DisposerRecord {
scaler context objects! */
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.
* For Truetype fonts we extract required info outside of scaler
* on java layer.
......
......@@ -167,6 +167,9 @@ class FreetypeFontScaler extends FontScaler {
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() {
if (nativeScaler != 0L) {
disposeNativeScaler(font.get(), nativeScaler);
......@@ -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 {
if (nativeScaler != 0L) {
return getNumGlyphsNative(nativeScaler);
......@@ -210,7 +228,7 @@ class FreetypeFontScaler extends FontScaler {
return getUnitsPerEMNative(nativeScaler);
}
long createScalerContext(double[] matrix,
synchronized long createScalerContext(double[] matrix,
int aa, int fm, float boldness, float italic,
boolean disableHinting) {
if (nativeScaler != 0L) {
......@@ -240,7 +258,7 @@ class FreetypeFontScaler extends FontScaler {
private native GeneralPath getGlyphVectorOutlineNative(Font2D font,
long pScalerContext, long pScaler,
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);
private native long getLayoutTableCacheNative(long pScaler);
......@@ -253,7 +271,7 @@ class FreetypeFontScaler extends FontScaler {
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);
/* Freetype scaler context does not contain any pointers that
......
......@@ -154,7 +154,31 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
jobject bBuffer;
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 */
if (numBytes > FILEDATACACHESIZE) {
......@@ -164,7 +188,11 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
scalerInfo->font2D,
sunFontIDs.ttReadBlockMID,
bBuffer, offset, numBytes);
return bread;
if (bread < 0) {
return 0;
} else {
return bread;
}
} else {
/* We probably hit bug bug 4845371. For reasons that
* are currently unclear, the call stacks after the initial
......@@ -179,9 +207,18 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
(*env)->CallObjectMethod(env, scalerInfo->font2D,
sunFontIDs.ttReadBytesMID,
offset, numBytes);
(*env)->GetByteArrayRegion(env, byteArray,
0, numBytes, (jbyte*)destBuffer);
return numBytes;
/* If there's an OutofMemoryError then byteArray will be null */
if (byteArray == NULL) {
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? */
else if (scalerInfo->fontDataOffset <= offset &&
......@@ -203,6 +240,11 @@ static unsigned long ReadTTFontFileFunc(FT_Stream stream,
sunFontIDs.ttReadBlockMID,
bBuffer, offset,
scalerInfo->fontDataLength);
if (bread <= 0) {
return 0;
} else if (bread < numBytes) {
numBytes = bread;
}
memcpy(destBuffer, scalerInfo->fontData, numBytes);
return numBytes;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册