rev 54094 : 8257853: Remove dependencies on JNF's JNI utility functions in AWT and 2D code
rev 54096 : 8259651: [macOS] Replace JNF_COCOA_ENTER/EXIT macros
rev 54098 : 8260616: Removing remaining JNF dependencies in the java.desktop module
8259729: Missed JNFInstanceOf -> IsInstanceOf conversion

   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 "java_awt_Font.h"
  27 #import "sun_awt_PlatformFont.h"
  28 #import "sun_awt_FontDescriptor.h"
  29 #import "sun_font_CFont.h"
  30 #import "sun_font_CFontManager.h"
  31 
  32 #import "AWTFont.h"
  33 #import "AWTStrike.h"
  34 #import "CoreTextSupport.h"
  35 #import "JNIUtilities.h"
  36 
  37 @implementation AWTFont
  38 
  39 - (id) initWithFont:(NSFont *)font {
  40     self = [super init];
  41     if (self) {
  42         fFont = [font retain];
  43         fNativeCGFont = CTFontCopyGraphicsFont((CTFontRef)font, NULL);
  44     }
  45     return self;
  46 }
  47 
  48 - (void) dealloc {
  49     [fFont release];
  50     fFont = nil;
  51 
  52     if (fNativeCGFont) {
  53         CGFontRelease(fNativeCGFont);
  54     fNativeCGFont = NULL;
  55     }
  56 
  57     [super dealloc];
  58 }
  59 
  60 - (void) finalize {
  61     if (fNativeCGFont) {
  62         CGFontRelease(fNativeCGFont);
  63     fNativeCGFont = NULL;
  64     }
  65     [super finalize];
  66 }
  67 
  68 static NSString* uiName = nil;
  69 static NSString* uiBoldName = nil;
  70 
  71 + (AWTFont *) awtFontForName:(NSString *)name
  72                        style:(int)style
  73 {
  74     // create font with family & size
  75     NSFont *nsFont = nil;
  76 
  77     if ((uiName != nil && [name isEqualTo:uiName]) ||
  78         (uiBoldName != nil && [name isEqualTo:uiBoldName])) {
  79         if (style & java_awt_Font_BOLD) {
  80             nsFont = [NSFont boldSystemFontOfSize:1.0];
  81         } else {
  82             nsFont = [NSFont systemFontOfSize:1.0];
  83         }
  84 #ifdef DEBUG
  85         NSLog(@"nsFont-name is : %@", nsFont.familyName);
  86         NSLog(@"nsFont-family is : %@", nsFont.fontName);
  87         NSLog(@"nsFont-desc-name is : %@", nsFont.fontDescriptor.postscriptName);
  88 #endif
  89 
  90 
  91     } else {
  92            nsFont = [NSFont fontWithName:name size:1.0];
  93     }
  94 
  95     if (nsFont == nil) {
  96         // if can't get font of that name, substitute system default font
  97         nsFont = [NSFont fontWithName:@"Lucida Grande" size:1.0];
  98 #ifdef DEBUG
  99         NSLog(@"needed to substitute Lucida Grande for: %@", name);
 100 #endif
 101     }
 102 
 103     // create an italic style (if one is installed)
 104     if (style & java_awt_Font_ITALIC) {
 105         nsFont = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSItalicFontMask];
 106     }
 107 
 108     // create a bold style (if one is installed)
 109     if (style & java_awt_Font_BOLD) {
 110         nsFont = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSBoldFontMask];
 111     }
 112 
 113     return [[[AWTFont alloc] initWithFont:nsFont] autorelease];
 114 }
 115 
 116 + (NSFont *) nsFontForJavaFont:(jobject)javaFont env:(JNIEnv *)env {
 117     if (javaFont == NULL) {
 118 #ifdef DEBUG
 119         NSLog(@"nil font");
 120 #endif
 121         return nil;
 122     }
 123 
 124     DECLARE_CLASS_RETURN(jc_Font, "java/awt/Font", nil);
 125 
 126     // obtain the Font2D
 127     DECLARE_METHOD_RETURN(jm_Font_getFont2D, jc_Font, "getFont2D", "()Lsun/font/Font2D;", nil);
 128     jobject font2d = (*env)->CallObjectMethod(env, javaFont, jm_Font_getFont2D);
 129     CHECK_EXCEPTION();
 130     if (font2d == NULL) {
 131 #ifdef DEBUG
 132         NSLog(@"nil font2d");
 133 #endif
 134         return nil;
 135     }
 136 
 137     // if it's not a CFont, it's likely one of TTF or OTF fonts
 138     // from the Sun rendering loops
 139     DECLARE_CLASS_RETURN(jc_CFont, "sun/font/CFont", nil);
 140     if (!(*env)->IsInstanceOf(env, font2d, jc_CFont)) {
 141 #ifdef DEBUG
 142         NSLog(@"font2d !instanceof CFont");
 143 #endif
 144         return nil;
 145     }
 146 
 147     DECLARE_METHOD_RETURN(jm_CFont_getFontStrike, jc_CFont, "getStrike", "(Ljava/awt/Font;)Lsun/font/FontStrike;", nil);
 148     jobject fontStrike = (*env)->CallObjectMethod(env, font2d, jm_CFont_getFontStrike, javaFont);
 149     CHECK_EXCEPTION();
 150     DECLARE_CLASS_RETURN(jc_CStrike, "sun/font/CStrike", nil);
 151     if (!(*env)->IsInstanceOf(env, fontStrike, jc_CStrike)) {
 152 #ifdef DEBUG
 153         NSLog(@"fontStrike !instanceof CStrike");
 154 #endif
 155         return nil;
 156     }
 157 
 158     DECLARE_METHOD_RETURN(jm_CStrike_nativeStrikePtr, jc_CStrike, "getNativeStrikePtr", "()J", nil);
 159     jlong awtStrikePtr = (*env)->CallLongMethod(env, fontStrike, jm_CStrike_nativeStrikePtr);
 160     CHECK_EXCEPTION();
 161     if (awtStrikePtr == 0L) {
 162 #ifdef DEBUG
 163         NSLog(@"nil nativeFontPtr from CFont");
 164 #endif
 165         return nil;
 166     }
 167 
 168     AWTStrike *strike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
 169 
 170     return [NSFont fontWithName:[strike->fAWTFont->fFont fontName] matrix:(CGFloat *)(&(strike->fAltTx))];
 171 }
 172 
 173 @end
 174 
 175 
 176 #pragma mark --- Font Discovery and Loading ---
 177 
 178 static NSArray* sFilteredFonts = nil;
 179 static NSDictionary* sFontFamilyTable = nil;
 180 
 181 static NSString*
 182 GetFamilyNameForFontName(NSString* fontname)
 183 {
 184     return [sFontFamilyTable objectForKey:fontname];
 185 }
 186 
 187 static void addFont(CTFontUIFontType uiType,
 188                     NSMutableArray *allFonts,
 189                     NSMutableDictionary* fontFamilyTable) {
 190 
 191         CTFontRef font = CTFontCreateUIFontForLanguage(uiType, 0.0, NULL);
 192         if (font == NULL) {
 193             return;
 194         }
 195         CTFontDescriptorRef desc = CTFontCopyFontDescriptor(font);
 196         if (desc == NULL) {
 197             CFRelease(font);
 198             return;
 199         }
 200         CFStringRef family = CTFontDescriptorCopyAttribute(desc, kCTFontFamilyNameAttribute);
 201         if (family == NULL) {
 202             CFRelease(desc);
 203             CFRelease(font);
 204             return;
 205         }
 206         CFStringRef name = CTFontDescriptorCopyAttribute(desc, kCTFontNameAttribute);
 207         if (name == NULL) {
 208             CFRelease(family);
 209             CFRelease(desc);
 210             CFRelease(font);
 211             return;
 212         }
 213         if (uiType == kCTFontUIFontSystem) {
 214             uiName = (NSString*)name;
 215         }
 216         if (uiType == kCTFontUIFontEmphasizedSystem) {
 217             uiBoldName = (NSString*)name;
 218         }
 219         [allFonts addObject:name];
 220         [fontFamilyTable setObject:family forKey:name];
 221 #ifdef DEBUG
 222         NSLog(@"name is : %@", (NSString*)name);
 223         NSLog(@"family is : %@", (NSString*)family);
 224 #endif
 225         CFRelease(family);
 226         CFRelease(name);
 227         CFRelease(desc);
 228         CFRelease(font);
 229 }
 230 
 231 static NSArray*
 232 GetFilteredFonts()
 233 {
 234     if (sFilteredFonts == nil) {
 235         NSFontManager *fontManager = [NSFontManager sharedFontManager];
 236         NSUInteger fontCount = [[fontManager availableFonts] count];
 237 
 238         NSMutableArray *allFonts = [[NSMutableArray alloc] initWithCapacity:fontCount];
 239         NSMutableDictionary* fontFamilyTable = [[NSMutableDictionary alloc] initWithCapacity:fontCount];
 240         NSArray *allFamilies = [fontManager availableFontFamilies];
 241 
 242         NSUInteger familyCount = [allFamilies count];
 243 
 244         NSUInteger familyIndex;
 245         for (familyIndex = 0; familyIndex < familyCount; familyIndex++) {
 246             NSString *family = [allFamilies objectAtIndex:familyIndex];
 247 
 248             if ((family == nil) || [family characterAtIndex:0] == '.') {
 249                 continue;
 250             }
 251 
 252             NSArray *fontFaces = [fontManager availableMembersOfFontFamily:family];
 253             NSUInteger faceCount = [fontFaces count];
 254 
 255             NSUInteger faceIndex;
 256             for (faceIndex = 0; faceIndex < faceCount; faceIndex++) {
 257                 NSString* face = [[fontFaces objectAtIndex:faceIndex] objectAtIndex:0];
 258                 if (face != nil) {
 259                     [allFonts addObject:face];
 260                     [fontFamilyTable setObject:family forKey:face];
 261                 }
 262             }
 263         }
 264 
 265         /*
 266          * JavaFX registers these fonts and so JDK needs to do so as well.
 267          * If this isn't done we will have mis-matched rendering, since
 268          * although these may include fonts that are enumerated normally
 269          * they also demonstrably includes fonts that are not.
 270          */
 271         addFont(kCTFontUIFontSystem, allFonts, fontFamilyTable);
 272         addFont(kCTFontUIFontEmphasizedSystem, allFonts, fontFamilyTable);
 273 
 274         sFilteredFonts = allFonts;
 275         sFontFamilyTable = fontFamilyTable;
 276     }
 277 
 278     return sFilteredFonts;
 279 }
 280 
 281 #pragma mark --- sun.font.CFontManager JNI ---
 282 
 283 static OSStatus CreateFSRef(FSRef *myFSRefPtr, NSString *inPath)
 284 {
 285     return FSPathMakeRef((UInt8 *)[inPath fileSystemRepresentation],
 286                          myFSRefPtr, NULL);
 287 }
 288 

































































 289 /*
 290  * Class:     sun_font_CFontManager
 291  * Method:    loadNativeFonts
 292  * Signature: ()V
 293  */
 294 JNIEXPORT void JNICALL
 295 Java_sun_font_CFontManager_loadNativeFonts
 296     (JNIEnv *env, jobject jthis)
 297 {
 298     DECLARE_CLASS(jc_CFontManager, "sun/font/CFontManager");
 299     DECLARE_METHOD(jm_registerFont, jc_CFontManager, "registerFont", "(Ljava/lang/String;Ljava/lang/String;)V");



 300 
 301     jint num = 0;
 302 
 303 JNI_COCOA_ENTER(env);
 304 
 305     NSArray *filteredFonts = GetFilteredFonts();
 306     num = (jint)[filteredFonts count];
 307 
 308     jint i;
 309     for (i = 0; i < num; i++) {
 310         NSString *fontname = [filteredFonts objectAtIndex:i];
 311         jobject jFontName = NSStringToJavaString(env, fontname);
 312         jobject jFontFamilyName =
 313             NSStringToJavaString(env, GetFamilyNameForFontName(fontname));
 314 
 315         (*env)->CallVoidMethod(env, jthis, jm_registerFont, jFontName, jFontFamilyName);
 316         CHECK_EXCEPTION();
 317         (*env)->DeleteLocalRef(env, jFontName);
 318         (*env)->DeleteLocalRef(env, jFontFamilyName);
 319     }
 320 
 321 JNI_COCOA_EXIT(env);
 322 }
 323 
 324 /*
 325  * Class:     Java_sun_font_CFontManager_loadNativeDirFonts
 326  * Method:    loadNativeDirFonts
 327  * Signature: (Ljava/lang/String;)V;
 328  */
 329 JNIEXPORT void JNICALL
 330 Java_sun_font_CFontManager_loadNativeDirFonts
 331 (JNIEnv *env, jclass clz, jstring filename)
 332 {
 333 JNI_COCOA_ENTER(env);
 334 
 335     NSString *path = JavaStringToNSString(env, filename);
 336     NSURL *url = [NSURL fileURLWithPath:(NSString *)path];
 337     bool res = CTFontManagerRegisterFontsForURL((CFURLRef)url, kCTFontManagerScopeProcess, nil);
 338 #ifdef DEBUG
 339     NSLog(@"path is : %@", (NSString*)path);
 340     NSLog(@"url is : %@", (NSString*)url);
 341     printf("res is %d\n", res);
 342 #endif
 343 JNI_COCOA_EXIT(env);
 344 }
 345 
 346 #pragma mark --- sun.font.CFont JNI ---
 347 
 348 /*
 349  * Class:     sun_font_CFont
 350  * Method:    getPlatformFontPtrNative
 351  * Signature: (JI)[B
 352  */
 353 JNIEXPORT jlong JNICALL
 354 Java_sun_font_CFont_getCGFontPtrNative
 355     (JNIEnv *env, jclass clazz,
 356      jlong awtFontPtr)
 357 {
 358     AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
 359     return (jlong)(awtFont->fNativeCGFont);
 360 }
 361 
 362 /*
 363  * Class:     sun_font_CFont
 364  * Method:    getTableBytesNative
 365  * Signature: (JI)[B
 366  */
 367 JNIEXPORT jbyteArray JNICALL
 368 Java_sun_font_CFont_getTableBytesNative
 369     (JNIEnv *env, jclass clazz,
 370      jlong awtFontPtr, jint jtag)
 371 {
 372     jbyteArray jbytes = NULL;
 373 JNI_COCOA_ENTER(env);
 374 
 375     CTFontTableTag tag = (CTFontTableTag)jtag;
 376     int i, found = 0;
 377     AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
 378     NSFont* nsFont = awtFont->fFont;
 379     CTFontRef ctfont = (CTFontRef)nsFont;
 380     CFArrayRef tagsArray =
 381         CTFontCopyAvailableTables(ctfont, kCTFontTableOptionNoOptions);
 382     CFIndex numTags = CFArrayGetCount(tagsArray);
 383     for (i=0; i<numTags; i++) {
 384         if (tag ==
 385             (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tagsArray, i)) {
 386             found = 1;
 387             break;
 388         }
 389     }
 390     CFRelease(tagsArray);
 391     if (!found) {
 392         return NULL;
 393     }
 394     CFDataRef table = CTFontCopyTable(ctfont, tag, kCTFontTableOptionNoOptions);
 395     if (table == NULL) {
 396         return NULL;
 397     }
 398 
 399     char *tableBytes = (char*)(CFDataGetBytePtr(table));
 400     size_t tableLength = CFDataGetLength(table);
 401     if (tableBytes == NULL || tableLength == 0) {
 402         CFRelease(table);
 403         return NULL;
 404     }
 405 
 406     jbytes = (*env)->NewByteArray(env, (jsize)tableLength);
 407     if (jbytes == NULL) {
 408         return NULL;
 409     }
 410     (*env)->SetByteArrayRegion(env, jbytes, 0,
 411                                (jsize)tableLength,
 412                                (jbyte*)tableBytes);
 413     CFRelease(table);
 414 
 415 JNI_COCOA_EXIT(env);
 416 
 417     return jbytes;
 418 }
 419 
 420 /*
 421  * Class:     sun_font_CFont
 422  * Method:    initNativeFont
 423  * Signature: (Ljava/lang/String;I)J
 424  */
 425 JNIEXPORT jlong JNICALL
 426 Java_sun_font_CFont_createNativeFont
 427     (JNIEnv *env, jclass clazz,
 428      jstring nativeFontName, jint style)
 429 {
 430     AWTFont *awtFont = nil;
 431 
 432 JNI_COCOA_ENTER(env);
 433 
 434     awtFont =
 435         [AWTFont awtFontForName:JavaStringToNSString(env, nativeFontName)
 436          style:style]; // autoreleased
 437 
 438     if (awtFont) {
 439         CFRetain(awtFont); // GC
 440     }
 441 
 442 JNI_COCOA_EXIT(env);
 443 
 444     return ptr_to_jlong(awtFont);
 445 }
 446 
 447 /*
 448  * Class:     sun_font_CFont
 449  * Method:    getWidthNative
 450  * Signature: (J)F
 451  */
 452 JNIEXPORT jfloat JNICALL
 453 Java_sun_font_CFont_getWidthNative
 454     (JNIEnv *env, jobject cfont, jlong awtFontPtr)
 455 {
 456     float widthVal;
 457 JNI_COCOA_ENTER(env);
 458 
 459     AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
 460     NSFont* nsFont = awtFont->fFont;
 461     NSFontDescriptor *fontDescriptor = nsFont.fontDescriptor;
 462     NSDictionary *fontTraits = [fontDescriptor objectForKey : NSFontTraitsAttribute];
 463     NSNumber *width = [fontTraits objectForKey : NSFontWidthTrait];
 464     widthVal = (float)[width floatValue];
 465 
 466 JNI_COCOA_EXIT(env);
 467    return (jfloat)widthVal;
 468 }
 469 
 470 /*
 471  * Class:     sun_font_CFont
 472  * Method:    getWeightNative
 473  * Signature: (J)F
 474  */
 475 JNIEXPORT jfloat JNICALL
 476 Java_sun_font_CFont_getWeightNative
 477     (JNIEnv *env, jobject cfont, jlong awtFontPtr)
 478 {
 479     float weightVal;
 480 JNI_COCOA_ENTER(env);
 481 
 482     AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
 483     NSFont* nsFont = awtFont->fFont;
 484     NSFontDescriptor *fontDescriptor = nsFont.fontDescriptor;
 485     NSDictionary *fontTraits = [fontDescriptor objectForKey : NSFontTraitsAttribute];
 486     NSNumber *weight = [fontTraits objectForKey : NSFontWeightTrait];
 487     weightVal = (float)[weight floatValue];
 488 
 489 JNI_COCOA_EXIT(env);
 490    return (jfloat)weightVal;
 491 }
 492 
 493 /*
 494  * Class:     sun_font_CFont
 495  * Method:    disposeNativeFont
 496  * Signature: (J)V
 497  */
 498 JNIEXPORT void JNICALL
 499 Java_sun_font_CFont_disposeNativeFont
 500     (JNIEnv *env, jclass clazz, jlong awtFontPtr)
 501 {
 502 JNI_COCOA_ENTER(env);
 503 
 504     if (awtFontPtr) {
 505         CFRelease((AWTFont *)jlong_to_ptr(awtFontPtr)); // GC
 506     }
 507 
 508 JNI_COCOA_EXIT(env);
 509 }
 510 
 511 
 512 #pragma mark --- Miscellaneous JNI ---
 513 
 514 #ifndef HEADLESS
 515 /*
 516  * Class:     sun_awt_PlatformFont
 517  * Method:    initIDs
 518  * Signature: ()V
 519  */
 520 JNIEXPORT void JNICALL
 521 Java_sun_awt_PlatformFont_initIDs
 522     (JNIEnv *env, jclass cls)
 523 {
 524 }
 525 
 526 /*
 527  * Class:     sun_awt_FontDescriptor
 528  * Method:    initIDs
 529  * Signature: ()V
 530  */
 531 JNIEXPORT void JNICALL
 532 Java_sun_awt_FontDescriptor_initIDs
 533     (JNIEnv *env, jclass cls)
 534 {
 535 }
 536 #endif
 537 
 538 /*
 539  * Class:     sun_awt_FontDescriptor
 540  * Method:    initIDs
 541  * Signature: ()V
 542  */
 543 JNIEXPORT void JNICALL
 544 Java_sun_font_CFont_getCascadeList
 545     (JNIEnv *env, jclass cls, jlong awtFontPtr, jobject arrayListOfString)
 546 {
 547     jclass alc = (*env)->FindClass(env, "java/util/ArrayList");
 548     if (alc == NULL) return;
 549     jmethodID addMID = (*env)->GetMethodID(env, alc, "add", "(Ljava/lang/Object;)Z");
 550     if (addMID == NULL) return;
 551 
 552     CFIndex i;
 553     AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
 554     NSFont* nsFont = awtFont->fFont;
 555     CTFontRef font = (CTFontRef)nsFont;
 556     CFStringRef base = CTFontCopyFullName(font);
 557     CFArrayRef codes = CFLocaleCopyISOLanguageCodes();
 558 
 559 #ifdef DEBUG
 560     NSLog(@"BaseFont is : %@", (NSString*)base);
 561 #endif
 562     CFArrayRef fds = CTFontCopyDefaultCascadeListForLanguages(font, codes);
 563     CFIndex cnt = CFArrayGetCount(fds);
 564     for (i=0; i<cnt; i++) {
 565         CTFontDescriptorRef ref = CFArrayGetValueAtIndex(fds, i);
 566         CFStringRef fontname =
 567             CTFontDescriptorCopyAttribute(ref, kCTFontNameAttribute);
 568 #ifdef DEBUG
 569         NSLog(@"Font is : %@", (NSString*)fontname);
 570 #endif
 571         jstring jFontName = (jstring)NSStringToJavaString(env, fontname);
 572         (*env)->CallBooleanMethod(env, arrayListOfString, addMID, jFontName);
 573         if ((*env)->ExceptionOccurred(env)) {
 574             return;
 575         }
 576         (*env)->DeleteLocalRef(env, jFontName);
 577     }
 578 }
--- EOF ---