1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   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 #import <JavaNativeFoundation/JavaNativeFoundation.h>
  27 
  28 #import "java_awt_Font.h"
  29 #import "sun_awt_PlatformFont.h"
  30 #import "sun_awt_FontDescriptor.h"
  31 #import "sun_font_CFont.h"
  32 #import "sun_font_CFontManager.h"
  33 
  34 #import "AWTFont.h"
  35 #import "AWTStrike.h"
  36 #import "CoreTextSupport.h"
  37 
  38 @implementation AWTFont
  39 
  40 - (id) initWithFont:(NSFont *)font {
  41     self = [super init];
  42     if (self) {
  43         fFont = [font retain];
  44         fNativeCGFont = CTFontCopyGraphicsFont((CTFontRef)font, NULL);
  45     }
  46     return self;
  47 }
  48 
  49 - (void) dealloc {
  50     [fFont release];
  51     fFont = nil;
  52 
  53     if (fNativeCGFont) {
  54         CGFontRelease(fNativeCGFont);
  55     fNativeCGFont = NULL;
  56     }
  57 
  58     [super dealloc];
  59 }
  60 
  61 - (void) finalize {
  62     if (fNativeCGFont) {
  63         CGFontRelease(fNativeCGFont);
  64     fNativeCGFont = NULL;
  65     }
  66     [super finalize];
  67 }
  68 
  69 + (AWTFont *) awtFontForName:(NSString *)name
  70                        style:(int)style
  71 {
  72     // create font with family & size
  73     NSFont *nsFont = [NSFont fontWithName:name size:1.0];
  74 
  75     if (nsFont == nil) {
  76         // if can't get font of that name, substitute system default font
  77         nsFont = [NSFont fontWithName:@"Lucida Grande" size:1.0];
  78 #ifdef DEBUG
  79         NSLog(@"needed to substitute Lucida Grande for: %@", name);
  80 #endif
  81     }
  82 
  83     // create an italic style (if one is installed)
  84     if (style & java_awt_Font_ITALIC) {
  85         nsFont = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSItalicFontMask];
  86     }
  87 
  88     // create a bold style (if one is installed)
  89     if (style & java_awt_Font_BOLD) {
  90         nsFont = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSBoldFontMask];
  91     }
  92 
  93     return [[[AWTFont alloc] initWithFont:nsFont] autorelease];
  94 }
  95 
  96 + (NSFont *) nsFontForJavaFont:(jobject)javaFont env:(JNIEnv *)env {
  97     if (javaFont == NULL) {
  98 #ifdef DEBUG
  99         NSLog(@"nil font");
 100 #endif
 101         return nil;
 102     }
 103 
 104     static JNF_CLASS_CACHE(jc_Font, "java/awt/Font");
 105 
 106     // obtain the Font2D
 107     static JNF_MEMBER_CACHE(jm_Font_getFont2D, jc_Font, "getFont2D", "()Lsun/font/Font2D;");
 108     jobject font2d = JNFCallObjectMethod(env, javaFont, jm_Font_getFont2D);
 109     if (font2d == NULL) {
 110 #ifdef DEBUG
 111         NSLog(@"nil font2d");
 112 #endif
 113         return nil;
 114     }
 115 
 116     // if it's not a CFont, it's likely one of TTF or OTF fonts
 117     // from the Sun rendering loops
 118     static JNF_CLASS_CACHE(jc_CFont, "sun/font/CFont");
 119     if (!JNFIsInstanceOf(env, font2d, &jc_CFont)) {
 120 #ifdef DEBUG
 121         NSLog(@"font2d !instanceof CFont");
 122 #endif
 123         return nil;
 124     }
 125 
 126     static JNF_MEMBER_CACHE(jm_CFont_getFontStrike, jc_CFont, "getStrike", "(Ljava/awt/Font;)Lsun/font/FontStrike;");
 127     jobject fontStrike = JNFCallObjectMethod(env, font2d, jm_CFont_getFontStrike, javaFont);
 128 
 129     static JNF_CLASS_CACHE(jc_CStrike, "sun/font/CStrike");
 130     if (!JNFIsInstanceOf(env, fontStrike, &jc_CStrike)) {
 131 #ifdef DEBUG
 132         NSLog(@"fontStrike !instanceof CStrike");
 133 #endif
 134         return nil;
 135     }
 136 
 137     static JNF_MEMBER_CACHE(jm_CStrike_nativeStrikePtr, jc_CStrike, "getNativeStrikePtr", "()J");
 138     jlong awtStrikePtr = JNFCallLongMethod(env, fontStrike, jm_CStrike_nativeStrikePtr);
 139     if (awtStrikePtr == 0L) {
 140 #ifdef DEBUG
 141         NSLog(@"nil nativeFontPtr from CFont");
 142 #endif
 143         return nil;
 144     }
 145 
 146     AWTStrike *strike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
 147 
 148     return [NSFont fontWithName:[strike->fAWTFont->fFont fontName] matrix:(CGFloat *)(&(strike->fAltTx))];
 149 }
 150 
 151 @end
 152 
 153 
 154 #pragma mark --- Font Discovery and Loading ---
 155 
 156 static NSArray* sFilteredFonts = nil;
 157 static NSDictionary* sFontFamilyTable = nil;
 158 
 159 static NSString*
 160 GetFamilyNameForFontName(NSString* fontname)
 161 {
 162     return [sFontFamilyTable objectForKey:fontname];
 163 }
 164 
 165 static void addFont(CTFontUIFontType uiType, 
 166                     NSMutableArray *allFonts,
 167                     NSMutableDictionary* fontFamilyTable) {
 168 
 169         CTFontRef font = CTFontCreateUIFontForLanguage(uiType, 0.0, NULL);
 170         if (font == NULL) {
 171             return;
 172         }
 173         CTFontDescriptorRef desc = CTFontCopyFontDescriptor(font);
 174         if (desc == NULL) {
 175             CFRelease(font);
 176             return;
 177         }
 178         CFStringRef family = CTFontDescriptorCopyAttribute(desc, kCTFontFamilyNameAttribute);
 179         if (family == NULL) {
 180             CFRelease(desc);
 181             CFRelease(font);
 182             return;
 183         }
 184         CFStringRef name = CTFontDescriptorCopyAttribute(desc, kCTFontNameAttribute);
 185         if (name == NULL) {
 186             CFRelease(family);
 187             CFRelease(desc);
 188             CFRelease(font);
 189             return;
 190         }
 191         [allFonts addObject:name];
 192         [fontFamilyTable setObject:family forKey:name];
 193 #ifdef DEBUG
 194         NSLog(@"name is : %@", (NSString*)name);
 195         NSLog(@"family is : %@", (NSString*)family);
 196 #endif
 197         CFRelease(family);
 198         CFRelease(name);
 199         CFRelease(desc);
 200         CFRelease(font);
 201 }
 202  
 203 static NSArray*
 204 GetFilteredFonts()
 205 {
 206     if (sFilteredFonts == nil) {
 207         NSFontManager *fontManager = [NSFontManager sharedFontManager];
 208         NSUInteger fontCount = [[fontManager availableFonts] count];
 209 
 210         NSMutableArray *allFonts = [[NSMutableArray alloc] initWithCapacity:fontCount];
 211         NSMutableDictionary* fontFamilyTable = [[NSMutableDictionary alloc] initWithCapacity:fontCount];
 212         NSArray *allFamilies = [fontManager availableFontFamilies];
 213 
 214         NSUInteger familyCount = [allFamilies count];
 215 
 216         NSUInteger familyIndex;
 217         for (familyIndex = 0; familyIndex < familyCount; familyIndex++) {
 218             NSString *family = [allFamilies objectAtIndex:familyIndex];
 219 
 220             if ((family == nil) || [family characterAtIndex:0] == '.') {
 221                 continue;
 222             }
 223 
 224             NSArray *fontFaces = [fontManager availableMembersOfFontFamily:family];
 225             NSUInteger faceCount = [fontFaces count];
 226 
 227             NSUInteger faceIndex;
 228             for (faceIndex = 0; faceIndex < faceCount; faceIndex++) {
 229                 NSString* face = [[fontFaces objectAtIndex:faceIndex] objectAtIndex:0];
 230                 if (face != nil) {
 231                     [allFonts addObject:face];
 232                     [fontFamilyTable setObject:family forKey:face];
 233                 }
 234             }
 235         }
 236 
 237         /*
 238          * JavaFX registers these fonts and so JDK needs to do so as well.
 239          * If this isn't done we will have mis-matched rendering, since
 240          * although these may include fonts that are enumerated normally
 241          * they also demonstrably includes fonts that are not.
 242          */
 243         addFont(kCTFontUIFontSystem, allFonts, fontFamilyTable);
 244         addFont(kCTFontUIFontEmphasizedSystem, allFonts, fontFamilyTable);
 245         addFont(kCTFontUIFontUserFixedPitch, allFonts, fontFamilyTable);
 246 
 247         sFilteredFonts = allFonts;
 248         sFontFamilyTable = fontFamilyTable;
 249     }
 250 
 251     return sFilteredFonts;
 252 }
 253 
 254 #pragma mark --- sun.font.CFontManager JNI ---
 255 
 256 static OSStatus CreateFSRef(FSRef *myFSRefPtr, NSString *inPath)
 257 {
 258     return FSPathMakeRef((UInt8 *)[inPath fileSystemRepresentation],
 259                          myFSRefPtr, NULL);
 260 }
 261 
 262 // /*
 263 //  * Class:     sun_font_CFontManager
 264 //  * Method:    loadFileFont
 265 //  * Signature: (Ljava/lang/String;)Lsun/font/Font2D;
 266 //  */
 267 // JNIEXPORT /* sun.font.CFont */ jobject JNICALL
 268 // Java_sun_font_CFontManager_loadFileFont
 269 //     (JNIEnv *env, jclass obj, jstring fontpath)
 270 // {
 271 //     jobject result = NULL;
 272 //
 273 // JNF_COCOA_ENTER(env);
 274 //
 275 //     NSString *nsFilePath = JNFJavaToNSString(env, fontpath);
 276 //     jstring javaFontName = NULL;
 277 //
 278 //     //
 279 //     // Note: This API uses ATS and can therefore return Carbon error codes.
 280 //     // These codes can be found at:
 281 //     // http://developer.apple.com/techpubs/macosx/Carbon/Files/FileManager/File_Manager/ResultCodes/ResultCodes.html
 282 //     //
 283 //
 284 //     FSRef iFile;
 285 //     OSStatus status = CreateFSRef(&iFile, nsFilePath);
 286 //
 287 //     if (status == noErr) {
 288 //         ATSFontContainerRef oContainer;
 289 //         status = ATSFontActivateFromFileReference(&iFile, kATSFontContextLocal,
 290 //                                                   kATSFontFormatUnspecified,
 291 //                                                   NULL,
 292 //                                                   kATSOptionFlagsUseDataFork,
 293 //                                                   &oContainer);
 294 //         if (status == noErr) {
 295 //             ATSFontRef ioArray[1];
 296 //             ItemCount oCount;
 297 //             status = ATSFontFindFromContainer(oContainer,
 298 //                                               kATSOptionFlagsUseDataFork,
 299 //                                               1, ioArray, &oCount);
 300 //
 301 //             if (status == noErr) {
 302 //                 CFStringRef oName;
 303 //                 status = ATSFontGetPostScriptName(ioArray[0],
 304 //                                                   kATSOptionFlagsUseDataFork,
 305 //                                                   &oName);
 306 //                 if (status == noErr) {
 307 //                     javaFontName = JNFNSToJavaString(env, (NSString *)oName);
 308 //                     CFRelease(oName);
 309 //                 }
 310 //             }
 311 //         }
 312 //     }
 313 //
 314 //     if (javaFontName != NULL) {
 315 //         // create the CFont!
 316 //         static JNF_CLASS_CACHE(sjc_CFont, "sun/font/CFont");
 317 //         static JNF_CTOR_CACHE(sjf_CFont_ctor,
 318 //                               sjc_CFont, "(Ljava/lang/String;)V");
 319 //         result = JNFNewObject(env, sjf_CFont_ctor, javaFontName);
 320 //     }
 321 //
 322 // JNF_COCOA_EXIT(env);
 323 //
 324 //     return result;
 325 // }
 326 
 327 /*
 328  * Class:     sun_font_CFontManager
 329  * Method:    loadNativeFonts
 330  * Signature: ()V
 331  */
 332 JNIEXPORT void JNICALL
 333 Java_sun_font_CFontManager_loadNativeFonts
 334     (JNIEnv *env, jobject jthis)
 335 {
 336     static JNF_CLASS_CACHE(jc_CFontManager,
 337                            "sun/font/CFontManager");
 338     static JNF_MEMBER_CACHE(jm_registerFont, jc_CFontManager,
 339                             "registerFont",
 340                             "(Ljava/lang/String;Ljava/lang/String;)V");
 341 
 342     jint num = 0;
 343 
 344 JNF_COCOA_ENTER(env);
 345 
 346     NSArray *filteredFonts = GetFilteredFonts();
 347     num = (jint)[filteredFonts count];
 348 
 349     jint i;
 350     for (i = 0; i < num; i++) {
 351         NSString *fontname = [filteredFonts objectAtIndex:i];
 352         jobject jFontName = JNFNSToJavaString(env, fontname);
 353         jobject jFontFamilyName =
 354             JNFNSToJavaString(env, GetFamilyNameForFontName(fontname));
 355 
 356         JNFCallVoidMethod(env, jthis,
 357                           jm_registerFont, jFontName, jFontFamilyName);
 358         (*env)->DeleteLocalRef(env, jFontName);
 359         (*env)->DeleteLocalRef(env, jFontFamilyName);
 360     }
 361 
 362 JNF_COCOA_EXIT(env);
 363 }
 364 
 365 /*
 366  * Class:     Java_sun_font_CFontManager_loadNativeDirFonts
 367  * Method:    loadNativeDirFonts
 368  * Signature: (Ljava/lang/String;)V;
 369  */
 370 JNIEXPORT void JNICALL
 371 Java_sun_font_CFontManager_loadNativeDirFonts
 372 (JNIEnv *env, jclass clz, jstring filename)
 373 {
 374 JNF_COCOA_ENTER(env);
 375 
 376     NSString *path = JNFJavaToNSString(env, filename);
 377     NSURL *url = [NSURL fileURLWithPath:(NSString *)path];
 378     bool res = CTFontManagerRegisterFontsForURL((CFURLRef)url, kCTFontManagerScopeProcess, nil);
 379 #ifdef DEBUG
 380     NSLog(@"path is : %@", (NSString*)path);
 381     NSLog(@"url is : %@", (NSString*)url);
 382     printf("res is %d\n", res);
 383 #endif
 384 JNF_COCOA_EXIT(env);
 385 }
 386 
 387 #pragma mark --- sun.font.CFont JNI ---
 388 
 389 /*
 390  * Class:     sun_font_CFont
 391  * Method:    getPlatformFontPtrNative
 392  * Signature: (JI)[B
 393  */
 394 JNIEXPORT jlong JNICALL
 395 Java_sun_font_CFont_getCGFontPtrNative
 396     (JNIEnv *env, jclass clazz,
 397      jlong awtFontPtr)
 398 {
 399     AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
 400     return (jlong)(awtFont->fNativeCGFont);
 401 }
 402 
 403 /*
 404  * Class:     sun_font_CFont
 405  * Method:    getTableBytesNative
 406  * Signature: (JI)[B
 407  */
 408 JNIEXPORT jbyteArray JNICALL
 409 Java_sun_font_CFont_getTableBytesNative
 410     (JNIEnv *env, jclass clazz,
 411      jlong awtFontPtr, jint jtag)
 412 {
 413     jbyteArray jbytes = NULL;
 414 JNF_COCOA_ENTER(env);
 415 
 416     CTFontTableTag tag = (CTFontTableTag)jtag;
 417     int i, found = 0;
 418     AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
 419     NSFont* nsFont = awtFont->fFont;
 420     CTFontRef ctfont = (CTFontRef)nsFont;
 421     CFArrayRef tagsArray =
 422         CTFontCopyAvailableTables(ctfont, kCTFontTableOptionNoOptions);
 423     CFIndex numTags = CFArrayGetCount(tagsArray);
 424     for (i=0; i<numTags; i++) {
 425         if (tag ==
 426             (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tagsArray, i)) {
 427             found = 1;
 428             break;
 429         }
 430     }
 431     CFRelease(tagsArray);
 432     if (!found) {
 433         return NULL;
 434     }
 435     CFDataRef table = CTFontCopyTable(ctfont, tag, kCTFontTableOptionNoOptions);
 436     if (table == NULL) {
 437         return NULL;
 438     }
 439 
 440     char *tableBytes = (char*)(CFDataGetBytePtr(table));
 441     size_t tableLength = CFDataGetLength(table);
 442     if (tableBytes == NULL || tableLength == 0) {
 443         CFRelease(table);
 444         return NULL;
 445     }
 446 
 447     jbytes = (*env)->NewByteArray(env, (jsize)tableLength);
 448     if (jbytes == NULL) {
 449         return NULL;
 450     }
 451     (*env)->SetByteArrayRegion(env, jbytes, 0,
 452                                (jsize)tableLength,
 453                                (jbyte*)tableBytes);
 454     CFRelease(table);
 455 
 456 JNF_COCOA_EXIT(env);
 457 
 458     return jbytes;
 459 }
 460 
 461 /*
 462  * Class:     sun_font_CFont
 463  * Method:    initNativeFont
 464  * Signature: (Ljava/lang/String;I)J
 465  */
 466 JNIEXPORT jlong JNICALL
 467 Java_sun_font_CFont_createNativeFont
 468     (JNIEnv *env, jclass clazz,
 469      jstring nativeFontName, jint style)
 470 {
 471     AWTFont *awtFont = nil;
 472 
 473 JNF_COCOA_ENTER(env);
 474 
 475     awtFont =
 476         [AWTFont awtFontForName:JNFJavaToNSString(env, nativeFontName)
 477          style:style]; // autoreleased
 478 
 479     if (awtFont) {
 480         CFRetain(awtFont); // GC
 481     }
 482 
 483 JNF_COCOA_EXIT(env);
 484 
 485     return ptr_to_jlong(awtFont);
 486 }
 487 
 488 /*
 489  * Class:     sun_font_CFont
 490  * Method:    getWidthNative
 491  * Signature: (J)F
 492  */
 493 JNIEXPORT jfloat JNICALL
 494 Java_sun_font_CFont_getWidthNative
 495     (JNIEnv *env, jobject cfont, jlong awtFontPtr)
 496 {
 497     float widthVal;
 498 JNF_COCOA_ENTER(env);
 499 
 500     AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
 501     NSFont* nsFont = awtFont->fFont;
 502     NSFontDescriptor *fontDescriptor = nsFont.fontDescriptor;
 503     NSDictionary *fontTraits = [fontDescriptor objectForKey : NSFontTraitsAttribute];
 504     NSNumber *width = [fontTraits objectForKey : NSFontWidthTrait];
 505     widthVal = (float)[width floatValue];
 506 
 507 JNF_COCOA_EXIT(env);
 508    return (jfloat)widthVal;
 509 }
 510 
 511 /*
 512  * Class:     sun_font_CFont
 513  * Method:    getWeightNative
 514  * Signature: (J)F
 515  */
 516 JNIEXPORT jfloat JNICALL
 517 Java_sun_font_CFont_getWeightNative
 518     (JNIEnv *env, jobject cfont, jlong awtFontPtr)
 519 {
 520     float weightVal;
 521 JNF_COCOA_ENTER(env);
 522 
 523     AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
 524     NSFont* nsFont = awtFont->fFont;
 525     NSFontDescriptor *fontDescriptor = nsFont.fontDescriptor;
 526     NSDictionary *fontTraits = [fontDescriptor objectForKey : NSFontTraitsAttribute];
 527     NSNumber *weight = [fontTraits objectForKey : NSFontWeightTrait];
 528     weightVal = (float)[weight floatValue];
 529 
 530 JNF_COCOA_EXIT(env);
 531    return (jfloat)weightVal;
 532 }
 533 
 534 /*
 535  * Class:     sun_font_CFont
 536  * Method:    disposeNativeFont
 537  * Signature: (J)V
 538  */
 539 JNIEXPORT void JNICALL
 540 Java_sun_font_CFont_disposeNativeFont
 541     (JNIEnv *env, jclass clazz, jlong awtFontPtr)
 542 {
 543 JNF_COCOA_ENTER(env);
 544 
 545     if (awtFontPtr) {
 546         CFRelease((AWTFont *)jlong_to_ptr(awtFontPtr)); // GC
 547     }
 548 
 549 JNF_COCOA_EXIT(env);
 550 }
 551 
 552 
 553 #pragma mark --- Miscellaneous JNI ---
 554 
 555 #ifndef HEADLESS
 556 /*
 557  * Class:     sun_awt_PlatformFont
 558  * Method:    initIDs
 559  * Signature: ()V
 560  */
 561 JNIEXPORT void JNICALL
 562 Java_sun_awt_PlatformFont_initIDs
 563     (JNIEnv *env, jclass cls)
 564 {
 565 }
 566 
 567 /*
 568  * Class:     sun_awt_FontDescriptor
 569  * Method:    initIDs
 570  * Signature: ()V
 571  */
 572 JNIEXPORT void JNICALL
 573 Java_sun_awt_FontDescriptor_initIDs
 574     (JNIEnv *env, jclass cls)
 575 {
 576 }
 577 #endif
 578 
 579 /*
 580  * Class:     sun_awt_FontDescriptor
 581  * Method:    initIDs
 582  * Signature: ()V
 583  */
 584 JNIEXPORT void JNICALL
 585 Java_sun_font_CFont_getCascadeList
 586     (JNIEnv *env, jclass cls, jlong awtFontPtr, jobject arrayListOfString)
 587 {
 588     jclass alc = (*env)->FindClass(env, "java/util/ArrayList");
 589     if (alc == NULL) return;
 590     jmethodID addMID = (*env)->GetMethodID(env, alc, "add", "(Ljava/lang/Object;)Z");
 591     if (addMID == NULL) return;
 592 
 593     CFIndex i;
 594     AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
 595     NSFont* nsFont = awtFont->fFont;
 596     CTFontRef font = (CTFontRef)nsFont;
 597     CFStringRef base = CTFontCopyFullName(font);
 598     CFArrayRef codes = CFLocaleCopyISOLanguageCodes();
 599 
 600 #ifdef DEBUG
 601     NSLog(@"BaseFont is : %@", (NSString*)base);
 602 #endif
 603     CFArrayRef fds = CTFontCopyDefaultCascadeListForLanguages(font, codes);
 604     CFIndex cnt = CFArrayGetCount(fds);
 605     for (i=0; i<cnt; i++) {
 606         CTFontDescriptorRef ref = CFArrayGetValueAtIndex(fds, i);
 607         CFStringRef fontname =
 608             CTFontDescriptorCopyAttribute(ref, kCTFontNameAttribute);
 609 #ifdef DEBUG
 610         NSLog(@"Font is : %@", (NSString*)fontname);
 611 #endif
 612         jstring jFontName = (jstring)JNFNSToJavaString(env, fontname);
 613         (*env)->CallBooleanMethod(env, arrayListOfString, addMID, jFontName); 
 614         (*env)->DeleteLocalRef(env, jFontName);
 615     }
 616 }