271 } |
271 } |
272 |
272 |
273 static void _do_nothing(void) { |
273 static void _do_nothing(void) { |
274 } |
274 } |
275 |
275 |
|
276 static void _free_nothing(void*) { |
|
277 } |
|
278 |
276 static hb_blob_t * |
279 static hb_blob_t * |
277 reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) { |
280 reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) { |
278 |
281 |
279 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)user_data; |
282 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)user_data; |
280 JNIEnv* env = jdkFontInfo->env; |
283 JNIEnv* env = jdkFontInfo->env; |
281 jobject font2D = jdkFontInfo->font2D; |
284 jobject font2D = jdkFontInfo->font2D; |
282 jsize length; |
285 jsize length = 0; |
283 jbyte* buffer; |
286 void* buffer = NULL; |
|
287 int cacheIdx = 0; |
284 |
288 |
285 // HB_TAG_NONE is 0 and is used to get the whole font file. |
289 // HB_TAG_NONE is 0 and is used to get the whole font file. |
286 // It is not expected not be needed for JDK. |
290 // It is not expected to be needed for JDK. |
287 if (tag == 0) { |
291 if (tag == 0 || jdkFontInfo->layoutTables == NULL) { |
288 return NULL; |
292 return NULL; |
289 } |
293 } |
290 jbyteArray tableBytes = (jbyteArray) |
294 |
291 env->CallObjectMethod(font2D, sunFontIDs.getTableBytesMID, tag); |
295 for (cacheIdx=0; cacheIdx<LAYOUTCACHE_ENTRIES; cacheIdx++) { |
292 if (tableBytes == NULL) { |
296 if (tag == jdkFontInfo->layoutTables->entries[cacheIdx].tag) break; |
293 return NULL; |
297 } |
294 } |
298 |
295 length = env->GetArrayLength(tableBytes); |
299 if (cacheIdx < LAYOUTCACHE_ENTRIES) { // if found |
296 buffer = (jbyte *)calloc(length, sizeof(jbyte)); |
300 if (jdkFontInfo->layoutTables->entries[cacheIdx].len != -1) { |
297 env->GetByteArrayRegion(tableBytes, 0, length, buffer); |
301 length = jdkFontInfo->layoutTables->entries[cacheIdx].len; |
|
302 buffer = (void*)jdkFontInfo->layoutTables->entries[cacheIdx].ptr; |
|
303 } |
|
304 } |
|
305 |
|
306 if (buffer == NULL) { |
|
307 jbyteArray tableBytes = (jbyteArray) |
|
308 env->CallObjectMethod(font2D, sunFontIDs.getTableBytesMID, tag); |
|
309 if (tableBytes == NULL) { |
|
310 return NULL; |
|
311 } |
|
312 length = env->GetArrayLength(tableBytes); |
|
313 buffer = calloc(length, sizeof(jbyte)); |
|
314 env->GetByteArrayRegion(tableBytes, 0, length, (jbyte*)buffer); |
|
315 |
|
316 if (cacheIdx >= LAYOUTCACHE_ENTRIES) { // not a cacheable table |
|
317 return hb_blob_create((const char *)buffer, length, |
|
318 HB_MEMORY_MODE_WRITABLE, |
|
319 buffer, free); |
|
320 } else { |
|
321 jdkFontInfo->layoutTables->entries[cacheIdx].len = length; |
|
322 jdkFontInfo->layoutTables->entries[cacheIdx].ptr = buffer; |
|
323 } |
|
324 } |
298 |
325 |
299 return hb_blob_create((const char *)buffer, length, |
326 return hb_blob_create((const char *)buffer, length, |
300 HB_MEMORY_MODE_WRITABLE, |
327 HB_MEMORY_MODE_READONLY, |
301 buffer, free); |
328 NULL, _free_nothing); |
302 } |
329 } |
|
330 |
|
331 |
303 |
332 |
304 hb_face_t* |
333 hb_face_t* |
305 hb_jdk_face_create(JDKFontInfo *jdkFontInfo, |
334 hb_jdk_face_create(JDKFontInfo *jdkFontInfo, |
306 hb_destroy_func_t destroy) { |
335 hb_destroy_func_t destroy) { |
307 |
336 |