8186317: Cache font layout tables for use by harfbuzz

Reviewed-by: srl, pnarayanan
This commit is contained in:
Phil Race 2017-08-28 11:53:44 -07:00
parent 05aa9c6d1d
commit 4211e523ea
6 changed files with 61 additions and 17 deletions

View File

@ -192,7 +192,8 @@ public final class SunLayoutEngine implements LayoutEngine, LayoutEngineFactory
if (font instanceof FileFont) { if (font instanceof FileFont) {
pScaler = ((FileFont)font).getScaler().nativeScaler; pScaler = ((FileFont)font).getScaler().nativeScaler;
} }
shape(font, strike, ptSize, mat, pScaler, pNativeFont, isAAT(font), shape(font, strike, ptSize, mat, pScaler, pNativeFont,
layoutTables, isAAT(font),
tr.text, data, key.script(), tr.text, data, key.script(),
tr.start, tr.limit, baseIndex, pt, tr.start, tr.limit, baseIndex, pt,
typo_flags, gmask); typo_flags, gmask);
@ -210,7 +211,7 @@ public final class SunLayoutEngine implements LayoutEngine, LayoutEngineFactory
/* Native method to invoke harfbuzz layout engine */ /* Native method to invoke harfbuzz layout engine */
private static native boolean private static native boolean
shape(Font2D font, FontStrike strike, float ptSize, float[] mat, shape(Font2D font, FontStrike strike, float ptSize, float[] mat,
long pscaler, long pNativeFont, boolean aat, long pscaler, long pNativeFont, long layoutTables, boolean aat,
char[] chars, GVData data, char[] chars, GVData data,
int script, int offset, int limit, int script, int offset, int limit,
int baseIndex, Point2D.Float pt, int typo_flags, int slot); int baseIndex, Point2D.Float pt, int typo_flags, int slot);

View File

@ -119,6 +119,7 @@ typedef struct GlyphInfo {
#define GSUB_TAG 0x47535542 /* 'GSUB' */ #define GSUB_TAG 0x47535542 /* 'GSUB' */
#define GPOS_TAG 0x47504F53 /* 'GPOS' */ #define GPOS_TAG 0x47504F53 /* 'GPOS' */
#define GDEF_TAG 0x47444546 /* 'GDEF' */ #define GDEF_TAG 0x47444546 /* 'GDEF' */
#define HEAD_TAG 0x68656164 /* 'head' */
#define MORT_TAG 0x6D6F7274 /* 'mort' */ #define MORT_TAG 0x6D6F7274 /* 'mort' */
#define MORX_TAG 0x6D6F7278 /* 'morx' */ #define MORX_TAG 0x6D6F7278 /* 'morx' */
#define KERN_TAG 0x6B65726E /* 'kern' */ #define KERN_TAG 0x6B65726E /* 'kern' */
@ -126,9 +127,10 @@ typedef struct GlyphInfo {
typedef struct TTLayoutTableCacheEntry { typedef struct TTLayoutTableCacheEntry {
const void* ptr; const void* ptr;
int len; int len;
int tag;
} TTLayoutTableCacheEntry; } TTLayoutTableCacheEntry;
#define LAYOUTCACHE_ENTRIES 6 #define LAYOUTCACHE_ENTRIES 7
typedef struct TTLayoutTableCache { typedef struct TTLayoutTableCache {
TTLayoutTableCacheEntry entries[LAYOUTCACHE_ENTRIES]; TTLayoutTableCacheEntry entries[LAYOUTCACHE_ENTRIES];

View File

@ -203,6 +203,7 @@ JDKFontInfo*
jfloat ptSize, jfloat ptSize,
jlong pScaler, jlong pScaler,
jlong pNativeFont, jlong pNativeFont,
jlong layoutTables,
jfloatArray matrix, jfloatArray matrix,
jboolean aat) { jboolean aat) {
@ -215,6 +216,7 @@ JDKFontInfo*
fi->font2D = font2D; fi->font2D = font2D;
fi->fontStrike = fontStrike; fi->fontStrike = fontStrike;
fi->nativeFont = pNativeFont; fi->nativeFont = pNativeFont;
fi->layoutTables = (TTLayoutTableCache*)layoutTables;
fi->aat = aat; fi->aat = aat;
(*env)->GetFloatArrayRegion(env, matrix, 0, 4, fi->matrix); (*env)->GetFloatArrayRegion(env, matrix, 0, 4, fi->matrix);
fi->ptSize = ptSize; fi->ptSize = ptSize;
@ -241,6 +243,7 @@ JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape
jfloatArray matrix, jfloatArray matrix,
jlong pScaler, jlong pScaler,
jlong pNativeFont, jlong pNativeFont,
jlong layoutTables,
jboolean aat, jboolean aat,
jcharArray text, jcharArray text,
jobject gvdata, jobject gvdata,
@ -269,7 +272,7 @@ JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape
JDKFontInfo *jdkFontInfo = JDKFontInfo *jdkFontInfo =
createJDKFontInfo(env, font2D, fontStrike, ptSize, createJDKFontInfo(env, font2D, fontStrike, ptSize,
pScaler, pNativeFont, matrix, aat); pScaler, pNativeFont, layoutTables, matrix, aat);
if (!jdkFontInfo) { if (!jdkFontInfo) {
return JNI_FALSE; return JNI_FALSE;
} }

View File

@ -273,34 +273,63 @@ _hb_jdk_get_font_funcs (void)
static void _do_nothing(void) { static void _do_nothing(void) {
} }
static void _free_nothing(void*) {
}
static hb_blob_t * static hb_blob_t *
reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) { reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) {
JDKFontInfo *jdkFontInfo = (JDKFontInfo*)user_data; JDKFontInfo *jdkFontInfo = (JDKFontInfo*)user_data;
JNIEnv* env = jdkFontInfo->env; JNIEnv* env = jdkFontInfo->env;
jobject font2D = jdkFontInfo->font2D; jobject font2D = jdkFontInfo->font2D;
jsize length; jsize length = 0;
jbyte* buffer; void* buffer = NULL;
int cacheIdx = 0;
// HB_TAG_NONE is 0 and is used to get the whole font file. // HB_TAG_NONE is 0 and is used to get the whole font file.
// It is not expected not be needed for JDK. // It is not expected to be needed for JDK.
if (tag == 0) { if (tag == 0 || jdkFontInfo->layoutTables == NULL) {
return NULL; return NULL;
} }
for (cacheIdx=0; cacheIdx<LAYOUTCACHE_ENTRIES; cacheIdx++) {
if (tag == jdkFontInfo->layoutTables->entries[cacheIdx].tag) break;
}
if (cacheIdx < LAYOUTCACHE_ENTRIES) { // if found
if (jdkFontInfo->layoutTables->entries[cacheIdx].len != -1) {
length = jdkFontInfo->layoutTables->entries[cacheIdx].len;
buffer = (void*)jdkFontInfo->layoutTables->entries[cacheIdx].ptr;
}
}
if (buffer == NULL) {
jbyteArray tableBytes = (jbyteArray) jbyteArray tableBytes = (jbyteArray)
env->CallObjectMethod(font2D, sunFontIDs.getTableBytesMID, tag); env->CallObjectMethod(font2D, sunFontIDs.getTableBytesMID, tag);
if (tableBytes == NULL) { if (tableBytes == NULL) {
return NULL; return NULL;
} }
length = env->GetArrayLength(tableBytes); length = env->GetArrayLength(tableBytes);
buffer = (jbyte *)calloc(length, sizeof(jbyte)); buffer = calloc(length, sizeof(jbyte));
env->GetByteArrayRegion(tableBytes, 0, length, buffer); env->GetByteArrayRegion(tableBytes, 0, length, (jbyte*)buffer);
if (cacheIdx >= LAYOUTCACHE_ENTRIES) { // not a cacheable table
return hb_blob_create((const char *)buffer, length, return hb_blob_create((const char *)buffer, length,
HB_MEMORY_MODE_WRITABLE, HB_MEMORY_MODE_WRITABLE,
buffer, free); buffer, free);
} else {
jdkFontInfo->layoutTables->entries[cacheIdx].len = length;
jdkFontInfo->layoutTables->entries[cacheIdx].ptr = buffer;
}
}
return hb_blob_create((const char *)buffer, length,
HB_MEMORY_MODE_READONLY,
NULL, _free_nothing);
} }
hb_face_t* hb_face_t*
hb_jdk_face_create(JDKFontInfo *jdkFontInfo, hb_jdk_face_create(JDKFontInfo *jdkFontInfo,
hb_destroy_func_t destroy) { hb_destroy_func_t destroy) {

View File

@ -29,6 +29,7 @@
#include "hb.h" #include "hb.h"
#include <jni.h> #include <jni.h>
#include <sunfontids.h> #include <sunfontids.h>
#include <fontscalerdefs.h>
# ifdef __cplusplus # ifdef __cplusplus
extern "C" { extern "C" {
@ -39,6 +40,7 @@ typedef struct JDKFontInfo_Struct {
jobject font2D; jobject font2D;
jobject fontStrike; jobject fontStrike;
long nativeFont; long nativeFont;
TTLayoutTableCache *layoutTables;
float matrix[4]; float matrix[4];
float ptSize; float ptSize;
float xPtSize; float xPtSize;

View File

@ -350,6 +350,13 @@ JNIEXPORT TTLayoutTableCache* newLayoutTableCache() {
for(i=0;i<LAYOUTCACHE_ENTRIES;i++) { for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {
ltc->entries[i].len = -1; ltc->entries[i].len = -1;
} }
ltc->entries[0].tag = GDEF_TAG;
ltc->entries[1].tag = GPOS_TAG;
ltc->entries[2].tag = GSUB_TAG;
ltc->entries[3].tag = HEAD_TAG;
ltc->entries[4].tag = KERN_TAG;
ltc->entries[5].tag = MORT_TAG;
ltc->entries[6].tag = MORX_TAG;
} }
return ltc; return ltc;
} }