8186317: Cache font layout tables for use by harfbuzz
Reviewed-by: srl, pnarayanan
This commit is contained in:
parent
05aa9c6d1d
commit
4211e523ea
@ -192,7 +192,8 @@ public final class SunLayoutEngine implements LayoutEngine, LayoutEngineFactory
|
||||
if (font instanceof FileFont) {
|
||||
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.start, tr.limit, baseIndex, pt,
|
||||
typo_flags, gmask);
|
||||
@ -210,7 +211,7 @@ public final class SunLayoutEngine implements LayoutEngine, LayoutEngineFactory
|
||||
/* Native method to invoke harfbuzz layout engine */
|
||||
private static native boolean
|
||||
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,
|
||||
int script, int offset, int limit,
|
||||
int baseIndex, Point2D.Float pt, int typo_flags, int slot);
|
||||
|
@ -119,6 +119,7 @@ typedef struct GlyphInfo {
|
||||
#define GSUB_TAG 0x47535542 /* 'GSUB' */
|
||||
#define GPOS_TAG 0x47504F53 /* 'GPOS' */
|
||||
#define GDEF_TAG 0x47444546 /* 'GDEF' */
|
||||
#define HEAD_TAG 0x68656164 /* 'head' */
|
||||
#define MORT_TAG 0x6D6F7274 /* 'mort' */
|
||||
#define MORX_TAG 0x6D6F7278 /* 'morx' */
|
||||
#define KERN_TAG 0x6B65726E /* 'kern' */
|
||||
@ -126,9 +127,10 @@ typedef struct GlyphInfo {
|
||||
typedef struct TTLayoutTableCacheEntry {
|
||||
const void* ptr;
|
||||
int len;
|
||||
int tag;
|
||||
} TTLayoutTableCacheEntry;
|
||||
|
||||
#define LAYOUTCACHE_ENTRIES 6
|
||||
#define LAYOUTCACHE_ENTRIES 7
|
||||
|
||||
typedef struct TTLayoutTableCache {
|
||||
TTLayoutTableCacheEntry entries[LAYOUTCACHE_ENTRIES];
|
||||
|
@ -203,6 +203,7 @@ JDKFontInfo*
|
||||
jfloat ptSize,
|
||||
jlong pScaler,
|
||||
jlong pNativeFont,
|
||||
jlong layoutTables,
|
||||
jfloatArray matrix,
|
||||
jboolean aat) {
|
||||
|
||||
@ -215,6 +216,7 @@ JDKFontInfo*
|
||||
fi->font2D = font2D;
|
||||
fi->fontStrike = fontStrike;
|
||||
fi->nativeFont = pNativeFont;
|
||||
fi->layoutTables = (TTLayoutTableCache*)layoutTables;
|
||||
fi->aat = aat;
|
||||
(*env)->GetFloatArrayRegion(env, matrix, 0, 4, fi->matrix);
|
||||
fi->ptSize = ptSize;
|
||||
@ -241,6 +243,7 @@ JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape
|
||||
jfloatArray matrix,
|
||||
jlong pScaler,
|
||||
jlong pNativeFont,
|
||||
jlong layoutTables,
|
||||
jboolean aat,
|
||||
jcharArray text,
|
||||
jobject gvdata,
|
||||
@ -269,7 +272,7 @@ JNIEXPORT jboolean JNICALL Java_sun_font_SunLayoutEngine_shape
|
||||
|
||||
JDKFontInfo *jdkFontInfo =
|
||||
createJDKFontInfo(env, font2D, fontStrike, ptSize,
|
||||
pScaler, pNativeFont, matrix, aat);
|
||||
pScaler, pNativeFont, layoutTables, matrix, aat);
|
||||
if (!jdkFontInfo) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
@ -273,34 +273,63 @@ _hb_jdk_get_font_funcs (void)
|
||||
static void _do_nothing(void) {
|
||||
}
|
||||
|
||||
static void _free_nothing(void*) {
|
||||
}
|
||||
|
||||
static hb_blob_t *
|
||||
reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) {
|
||||
|
||||
JDKFontInfo *jdkFontInfo = (JDKFontInfo*)user_data;
|
||||
JNIEnv* env = jdkFontInfo->env;
|
||||
jobject font2D = jdkFontInfo->font2D;
|
||||
jsize length;
|
||||
jbyte* buffer;
|
||||
jsize length = 0;
|
||||
void* buffer = NULL;
|
||||
int cacheIdx = 0;
|
||||
|
||||
// HB_TAG_NONE is 0 and is used to get the whole font file.
|
||||
// It is not expected not be needed for JDK.
|
||||
if (tag == 0) {
|
||||
// It is not expected to be needed for JDK.
|
||||
if (tag == 0 || jdkFontInfo->layoutTables == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
jbyteArray tableBytes = (jbyteArray)
|
||||
env->CallObjectMethod(font2D, sunFontIDs.getTableBytesMID, tag);
|
||||
if (tableBytes == 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)
|
||||
env->CallObjectMethod(font2D, sunFontIDs.getTableBytesMID, tag);
|
||||
if (tableBytes == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
length = env->GetArrayLength(tableBytes);
|
||||
buffer = calloc(length, sizeof(jbyte));
|
||||
env->GetByteArrayRegion(tableBytes, 0, length, (jbyte*)buffer);
|
||||
|
||||
if (cacheIdx >= LAYOUTCACHE_ENTRIES) { // not a cacheable table
|
||||
return hb_blob_create((const char *)buffer, length,
|
||||
HB_MEMORY_MODE_WRITABLE,
|
||||
buffer, free);
|
||||
} else {
|
||||
jdkFontInfo->layoutTables->entries[cacheIdx].len = length;
|
||||
jdkFontInfo->layoutTables->entries[cacheIdx].ptr = buffer;
|
||||
}
|
||||
}
|
||||
length = env->GetArrayLength(tableBytes);
|
||||
buffer = (jbyte *)calloc(length, sizeof(jbyte));
|
||||
env->GetByteArrayRegion(tableBytes, 0, length, buffer);
|
||||
|
||||
return hb_blob_create((const char *)buffer, length,
|
||||
HB_MEMORY_MODE_WRITABLE,
|
||||
buffer, free);
|
||||
HB_MEMORY_MODE_READONLY,
|
||||
NULL, _free_nothing);
|
||||
}
|
||||
|
||||
|
||||
|
||||
hb_face_t*
|
||||
hb_jdk_face_create(JDKFontInfo *jdkFontInfo,
|
||||
hb_destroy_func_t destroy) {
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "hb.h"
|
||||
#include <jni.h>
|
||||
#include <sunfontids.h>
|
||||
#include <fontscalerdefs.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -39,6 +40,7 @@ typedef struct JDKFontInfo_Struct {
|
||||
jobject font2D;
|
||||
jobject fontStrike;
|
||||
long nativeFont;
|
||||
TTLayoutTableCache *layoutTables;
|
||||
float matrix[4];
|
||||
float ptSize;
|
||||
float xPtSize;
|
||||
|
@ -350,6 +350,13 @@ JNIEXPORT TTLayoutTableCache* newLayoutTableCache() {
|
||||
for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user