From 4211e523eafb0c9918bcf7786360e8d3e3956fbc Mon Sep 17 00:00:00 2001 From: Phil Race Date: Mon, 28 Aug 2017 11:53:44 -0700 Subject: [PATCH] 8186317: Cache font layout tables for use by harfbuzz Reviewed-by: srl, pnarayanan --- .../classes/sun/font/SunLayoutEngine.java | 5 +- .../share/native/common/font/fontscalerdefs.h | 4 +- .../share/native/libfontmanager/HBShaper.c | 5 +- .../native/libfontmanager/hb-jdk-font.cc | 55 ++++++++++++++----- .../share/native/libfontmanager/hb-jdk.h | 2 + .../share/native/libfontmanager/sunFont.c | 7 +++ 6 files changed, 61 insertions(+), 17 deletions(-) diff --git a/jdk/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java b/jdk/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java index c7ab758c9a4..3375cfcef7b 100644 --- a/jdk/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java +++ b/jdk/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java @@ -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); diff --git a/jdk/src/java.desktop/share/native/common/font/fontscalerdefs.h b/jdk/src/java.desktop/share/native/common/font/fontscalerdefs.h index 2a53cd13c18..7e2290c347a 100644 --- a/jdk/src/java.desktop/share/native/common/font/fontscalerdefs.h +++ b/jdk/src/java.desktop/share/native/common/font/fontscalerdefs.h @@ -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]; diff --git a/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c b/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c index 41cf1864178..da5814311f2 100644 --- a/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c +++ b/jdk/src/java.desktop/share/native/libfontmanager/HBShaper.c @@ -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; } diff --git a/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc b/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc index 027d8d790d7..c2ecdb77bd0 100644 --- a/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc +++ b/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc @@ -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; cacheIdxlayoutTables->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) { diff --git a/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk.h b/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk.h index b62c8b1553b..b1de77ccff5 100644 --- a/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk.h +++ b/jdk/src/java.desktop/share/native/libfontmanager/hb-jdk.h @@ -29,6 +29,7 @@ #include "hb.h" #include #include +#include # 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; diff --git a/jdk/src/java.desktop/share/native/libfontmanager/sunFont.c b/jdk/src/java.desktop/share/native/libfontmanager/sunFont.c index 866752f99d1..9b382c89e09 100644 --- a/jdk/src/java.desktop/share/native/libfontmanager/sunFont.c +++ b/jdk/src/java.desktop/share/native/libfontmanager/sunFont.c @@ -350,6 +350,13 @@ JNIEXPORT TTLayoutTableCache* newLayoutTableCache() { for(i=0;ientries[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; }