< prev index next >
src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc
Print this page
@@ -21,10 +21,13 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
+#include "jlong.h"
+#include "sun_font_SunLayoutEngine.h"
+
#include "hb.h"
#include "hb-jdk.h"
#ifdef MACOSX
#include "hb-coretext.h"
#endif
@@ -302,121 +305,143 @@
}
static void _free_nothing(void*) {
}
+struct Font2DPtr {
+ JavaVM* vmPtr;
+ jweak font2DRef;
+};
+
+static void cleanupFontInfo(void* data) {
+ Font2DPtr* fontInfo;
+ JNIEnv* env;
+
+ fontInfo = (Font2DPtr*) data;
+ fontInfo->vmPtr->GetEnv((void**)&env, JNI_VERSION_1_1);
+ env->DeleteWeakGlobalRef(fontInfo->font2DRef);
+ free(data);
+}
+
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 = 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 to be needed for JDK.
- if (tag == 0 || jdkFontInfo->layoutTables == NULL) {
+ Font2DPtr *fontInfo;
+ JNIEnv* env;
+ jobject font2D;
+ jsize length;
+ jbyte* buffer;
+
+ fontInfo = (Font2DPtr*)user_data;
+ fontInfo->vmPtr->GetEnv((void**)&env, JNI_VERSION_1_1);
+ if (env == NULL) {
return NULL;
}
+ font2D = fontInfo->font2DRef;
- 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;
- }
+ // 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) {
+ return NULL;
}
-
- 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);
+ buffer = (jbyte *)calloc(length, sizeof(jbyte));
+ env->GetByteArrayRegion(tableBytes, 0, length, 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;
- }
- }
-
- return hb_blob_create((const char *)buffer, length,
- HB_MEMORY_MODE_READONLY,
- NULL, _free_nothing);
}
+extern "C" {
+/*
+ * Class: sun_font_SunLayoutEngine
+ * Method: createFace
+ * Signature: (Lsun/font/Font2D;ZJ)J
+ */
+JNIEXPORT jlong JNICALL Java_sun_font_SunLayoutEngine_createFace(JNIEnv *env,
+ jclass cls,
+ jobject font2D,
+ jboolean aat,
+ jlong platformFontPtr) {
+#ifdef MACOSX
+ if (aat && platformFontPtr) {
+ hb_face_t *face = hb_coretext_face_create((CGFontRef)platformFontPtr);
+ return ptr_to_jlong(face);
+ }
+#endif
+ Font2DPtr *fi = (Font2DPtr*)malloc(sizeof(Font2DPtr));
+ if (!fi) {
+ return 0;
+ }
+ JavaVM* vmPtr;
+ env->GetJavaVM(&vmPtr);
+ fi->vmPtr = vmPtr;
+ fi->font2DRef = env->NewWeakGlobalRef(font2D);
+ if (!fi->font2DRef) {
+ free(fi);
+ return 0;
+ }
+ hb_face_t *face = hb_face_create_for_tables(reference_table, fi,
+ cleanupFontInfo);
+ return ptr_to_jlong(face);
+}
-hb_face_t*
-hb_jdk_face_create(JDKFontInfo *jdkFontInfo,
- hb_destroy_func_t destroy) {
-
- hb_face_t *face =
- hb_face_create_for_tables(reference_table, jdkFontInfo, destroy);
-
- return face;
+/*
+ * Class: sun_font_SunLayoutEngine
+ * Method: disposeFace
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_sun_font_SunLayoutEngine_disposeFace(JNIEnv *env,
+ jclass cls,
+ jlong ptr) {
+ hb_face_t* face = (hb_face_t*) jlong_to_ptr(ptr);
+ hb_face_destroy(face);
}
-static hb_font_t* _hb_jdk_font_create(JDKFontInfo *jdkFontInfo,
+} // extern "C"
+
+static hb_font_t* _hb_jdk_font_create(hb_face_t* face,
+ JDKFontInfo *jdkFontInfo,
hb_destroy_func_t destroy) {
hb_font_t *font;
- hb_face_t *face;
- face = hb_jdk_face_create(jdkFontInfo, destroy);
font = hb_font_create(face);
- hb_face_destroy (face);
hb_font_set_funcs (font,
_hb_jdk_get_font_funcs (),
jdkFontInfo, (hb_destroy_func_t) _do_nothing);
hb_font_set_scale (font,
HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale),
HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale));
return font;
}
#ifdef MACOSX
-static hb_font_t* _hb_jdk_ct_font_create(JDKFontInfo *jdkFontInfo) {
+static hb_font_t* _hb_jdk_ct_font_create(hb_face_t* face,
+ JDKFontInfo *jdkFontInfo) {
hb_font_t *font = NULL;
- hb_face_t *face = NULL;
- if (jdkFontInfo->nativeFont == 0) {
- return NULL;
- }
- face = hb_coretext_face_create((CGFontRef)(jdkFontInfo->nativeFont));
font = hb_font_create(face);
- hb_face_destroy(face);
-
hb_font_set_scale(font,
HBFloatToFixed(jdkFontInfo->ptSize),
HBFloatToFixed(jdkFontInfo->ptSize));
return font;
}
#endif
-hb_font_t* hb_jdk_font_create(JDKFontInfo *jdkFontInfo,
+hb_font_t* hb_jdk_font_create(hb_face_t* hbFace,
+ JDKFontInfo *jdkFontInfo,
hb_destroy_func_t destroy) {
-
- hb_font_t* font = NULL;
-
#ifdef MACOSX
- if (jdkFontInfo->aat) {
- font = _hb_jdk_ct_font_create(jdkFontInfo);
+ if (jdkFontInfo->aat && jdkFontInfo->nativeFont) {
+ return _hb_jdk_ct_font_create(hbFace, jdkFontInfo);
}
#endif
- if (font == NULL) {
- font = _hb_jdk_font_create(jdkFontInfo, destroy);
- }
- return font;
+ return _hb_jdk_font_create(hbFace, jdkFontInfo, destroy);
}
< prev index next >