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