6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "hb.h" 27 #include "hb-jdk.h" 28 #ifdef MACOSX 29 #include "hb-coretext.h" 30 #endif 31 #include <stdlib.h> 32 33 #if defined(__GNUC__) && __GNUC__ >= 4 34 #define HB_UNUSED __attribute__((unused)) 35 #else 36 #define HB_UNUSED 37 #endif 38 39 static hb_bool_t 40 hb_jdk_get_glyph (hb_font_t *font HB_UNUSED, 41 void *font_data, 42 hb_codepoint_t unicode, 43 hb_codepoint_t variation_selector, 44 hb_codepoint_t *glyph, 45 void *user_data HB_UNUSED) 256 hb_jdk_get_glyph_h_kerning, NULL, NULL); 257 hb_font_funcs_set_glyph_v_kerning_func(ff, 258 hb_jdk_get_glyph_v_kerning, NULL, NULL); 259 hb_font_funcs_set_glyph_extents_func(ff, 260 hb_jdk_get_glyph_extents, NULL, NULL); 261 hb_font_funcs_set_glyph_contour_point_func(ff, 262 hb_jdk_get_glyph_contour_point, NULL, NULL); 263 hb_font_funcs_set_glyph_name_func(ff, 264 hb_jdk_get_glyph_name, NULL, NULL); 265 hb_font_funcs_set_glyph_from_name_func(ff, 266 hb_jdk_get_glyph_from_name, NULL, NULL); 267 hb_font_funcs_make_immutable(ff); // done setting functions. 268 jdk_ffuncs = ff; 269 } 270 return jdk_ffuncs; 271 } 272 273 static void _do_nothing(void) { 274 } 275 276 static hb_blob_t * 277 reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) { 278 279 JDKFontInfo *jdkFontInfo = (JDKFontInfo*)user_data; 280 JNIEnv* env = jdkFontInfo->env; 281 jobject font2D = jdkFontInfo->font2D; 282 jsize length; 283 jbyte* buffer; 284 285 // HB_TAG_NONE is 0 and is used to get the whole font file. 286 // It is not expected not be needed for JDK. 287 if (tag == 0) { 288 return NULL; 289 } 290 jbyteArray tableBytes = (jbyteArray) 291 env->CallObjectMethod(font2D, sunFontIDs.getTableBytesMID, tag); 292 if (tableBytes == NULL) { 293 return NULL; 294 } 295 length = env->GetArrayLength(tableBytes); 296 buffer = (jbyte *)calloc(length, sizeof(jbyte)); 297 env->GetByteArrayRegion(tableBytes, 0, length, buffer); 298 299 return hb_blob_create((const char *)buffer, length, 300 HB_MEMORY_MODE_WRITABLE, 301 buffer, free); 302 } 303 304 hb_face_t* 305 hb_jdk_face_create(JDKFontInfo *jdkFontInfo, 306 hb_destroy_func_t destroy) { 307 308 hb_face_t *face = 309 hb_face_create_for_tables(reference_table, jdkFontInfo, destroy); 310 311 return face; 312 } 313 314 static hb_font_t* _hb_jdk_font_create(JDKFontInfo *jdkFontInfo, 315 hb_destroy_func_t destroy) { 316 317 hb_font_t *font; 318 hb_face_t *face; 319 320 face = hb_jdk_face_create(jdkFontInfo, destroy); 321 font = hb_font_create(face); 322 hb_face_destroy (face); 323 hb_font_set_funcs (font, 324 _hb_jdk_get_font_funcs (), 325 jdkFontInfo, (hb_destroy_func_t) _do_nothing); 326 hb_font_set_scale (font, 327 HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale), 328 HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale)); 329 return font; 330 } 331 332 #ifdef MACOSX 333 static hb_font_t* _hb_jdk_ct_font_create(JDKFontInfo *jdkFontInfo) { 334 335 hb_font_t *font = NULL; 336 hb_face_t *face = NULL; 337 if (jdkFontInfo->nativeFont == 0) { 338 return NULL; 339 } 340 face = hb_coretext_face_create((CGFontRef)(jdkFontInfo->nativeFont)); 341 font = hb_font_create(face); 342 hb_face_destroy(face); 343 344 hb_font_set_scale(font, 345 HBFloatToFixed(jdkFontInfo->ptSize), 346 HBFloatToFixed(jdkFontInfo->ptSize)); 347 return font; 348 } 349 #endif 350 351 hb_font_t* hb_jdk_font_create(JDKFontInfo *jdkFontInfo, 352 hb_destroy_func_t destroy) { 353 354 hb_font_t* font = NULL; 355 356 #ifdef MACOSX 357 if (jdkFontInfo->aat) { 358 font = _hb_jdk_ct_font_create(jdkFontInfo); 359 } 360 #endif 361 if (font == NULL) { 362 font = _hb_jdk_font_create(jdkFontInfo, destroy); 363 } 364 return font; 365 } | 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "jlong.h" 27 #include "sun_font_Font2D.h" 28 #include "hb.h" 29 #include "hb-jdk.h" 30 #ifdef MACOSX 31 #include "hb-coretext.h" 32 #endif 33 #include <stdlib.h> 34 35 #if defined(__GNUC__) && __GNUC__ >= 4 36 #define HB_UNUSED __attribute__((unused)) 37 #else 38 #define HB_UNUSED 39 #endif 40 41 static hb_bool_t 42 hb_jdk_get_glyph (hb_font_t *font HB_UNUSED, 43 void *font_data, 44 hb_codepoint_t unicode, 45 hb_codepoint_t variation_selector, 46 hb_codepoint_t *glyph, 47 void *user_data HB_UNUSED) 258 hb_jdk_get_glyph_h_kerning, NULL, NULL); 259 hb_font_funcs_set_glyph_v_kerning_func(ff, 260 hb_jdk_get_glyph_v_kerning, NULL, NULL); 261 hb_font_funcs_set_glyph_extents_func(ff, 262 hb_jdk_get_glyph_extents, NULL, NULL); 263 hb_font_funcs_set_glyph_contour_point_func(ff, 264 hb_jdk_get_glyph_contour_point, NULL, NULL); 265 hb_font_funcs_set_glyph_name_func(ff, 266 hb_jdk_get_glyph_name, NULL, NULL); 267 hb_font_funcs_set_glyph_from_name_func(ff, 268 hb_jdk_get_glyph_from_name, NULL, NULL); 269 hb_font_funcs_make_immutable(ff); // done setting functions. 270 jdk_ffuncs = ff; 271 } 272 return jdk_ffuncs; 273 } 274 275 static void _do_nothing(void) { 276 } 277 278 struct Font2DPtr { 279 JavaVM* vmPtr; 280 jweak font2DRef; 281 }; 282 283 static void cleanupFontInfo(void* data) { 284 Font2DPtr* fontInfo; 285 JNIEnv* env; 286 287 fontInfo = (Font2DPtr*) data; 288 fontInfo->vmPtr->GetEnv((void**)&env, JNI_VERSION_1_1); 289 env->DeleteWeakGlobalRef(fontInfo->font2DRef); 290 free((void*)data); 291 } 292 293 static hb_blob_t * 294 reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) { 295 296 Font2DPtr *fontInfo; 297 JNIEnv* env; 298 jobject font2D; 299 jsize length; 300 jbyte* buffer; 301 302 fontInfo = (Font2DPtr*)user_data; 303 fontInfo->vmPtr->GetEnv((void**)&env, JNI_VERSION_1_1); 304 if (env == NULL) { 305 return NULL; 306 } 307 font2D = fontInfo->font2DRef; 308 309 // HB_TAG_NONE is 0 and is used to get the whole font file. 310 // It is not expected not be needed for JDK. 311 if (tag == 0) { 312 return NULL; 313 } 314 jbyteArray tableBytes = (jbyteArray) 315 env->CallObjectMethod(font2D, sunFontIDs.getTableBytesMID, tag); 316 if (tableBytes == NULL) { 317 return NULL; 318 } 319 length = env->GetArrayLength(tableBytes); 320 buffer = (jbyte *)calloc(length, sizeof(jbyte)); 321 env->GetByteArrayRegion(tableBytes, 0, length, buffer); 322 323 return hb_blob_create((const char *)buffer, length, 324 HB_MEMORY_MODE_WRITABLE, 325 buffer, free); 326 } 327 328 /* 329 * Class: sun_font_Font2D 330 * Method: createHarfbuzzFace 331 * Signature: (ZJ)J 332 */ 333 JNIEXPORT jlong JNICALL Java_sun_font_Font2D_createHarfbuzzFace(JNIEnv *env, jobject font2D, jboolean aat, jlong platformFontPtr) { 334 #ifdef MACOSX 335 if (aat && platformFontPtr) { 336 hb_face_t *face = hb_coretext_face_create((CGFontRef)platformFontPtr); 337 return ptr_to_jlong(face); 338 } 339 #endif 340 Font2DPtr *fi = (Font2DPtr*)malloc(sizeof(Font2DPtr)); 341 if (!fi) { 342 return 0; 343 } 344 JavaVM* vmPtr; 345 env->GetJavaVM(&vmPtr); 346 fi->vmPtr = vmPtr; 347 fi->font2DRef = env->NewWeakGlobalRef(font2D); 348 hb_face_t *face = hb_face_create_for_tables(reference_table, fi, cleanupFontInfo); 349 return ptr_to_jlong(face); 350 } 351 352 /* 353 * Class: sun_font_Font2D 354 * Method: disposeHarfbuzzFace 355 * Signature: (J)V 356 */ 357 JNIEXPORT void JNICALL Java_sun_font_Font2D_disposeHarfbuzzFace(JNIEnv *env, jclass cls, jlong ptr) { 358 hb_face_t* face = (hb_face_t*) jlong_to_ptr(ptr); 359 hb_face_destroy(face); 360 } 361 362 static hb_font_t* _hb_jdk_font_create(hb_face_t* face, 363 JDKFontInfo *jdkFontInfo, 364 hb_destroy_func_t destroy) { 365 366 hb_font_t *font; 367 368 font = hb_font_create(face); 369 hb_font_set_funcs (font, 370 _hb_jdk_get_font_funcs (), 371 jdkFontInfo, (hb_destroy_func_t) _do_nothing); 372 hb_font_set_scale (font, 373 HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale), 374 HBFloatToFixed(jdkFontInfo->ptSize*jdkFontInfo->devScale)); 375 return font; 376 } 377 378 #ifdef MACOSX 379 static hb_font_t* _hb_jdk_ct_font_create(hb_face_t* face, JDKFontInfo *jdkFontInfo) { 380 381 hb_font_t *font = NULL; 382 font = hb_font_create(face); 383 hb_font_set_scale(font, 384 HBFloatToFixed(jdkFontInfo->ptSize), 385 HBFloatToFixed(jdkFontInfo->ptSize)); 386 return font; 387 } 388 #endif 389 390 hb_font_t* hb_jdk_font_create(hb_face_t* hbface, 391 JDKFontInfo *jdkFontInfo, 392 hb_destroy_func_t destroy) { 393 394 hb_font_t* font = NULL; 395 396 #ifdef MACOSX 397 if (jdkFontInfo->aat && jdkFontInfo->nativeFont) { 398 font = _hb_jdk_ct_font_create(hbface, jdkFontInfo); 399 } 400 #endif 401 if (font == NULL) { 402 font = _hb_jdk_font_create(hbface, jdkFontInfo, destroy); 403 } 404 return font; 405 } |