Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/native/sun/font/AWTFont.m
38829 views
/*1* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#ifdef MACOSX_NOTIOS // prevent merge conflicts26#import <JavaNativeFoundation/JavaNativeFoundation.h>2728#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"3334#import "AWTFont.h"35#import "AWTStrike.h"36#import "CoreTextSupport.h"3738@implementation AWTFont3940- (id) initWithFont:(NSFont *)font {41self = [super init];42if (self) {43fFont = [font retain];44fNativeCGFont = CTFontCopyGraphicsFont((CTFontRef)font, NULL);45layoutTableCache = NULL;46}47return self;48}4950static TTLayoutTableCache* newCFontLayoutTableCache() {51TTLayoutTableCache* ltc = calloc(1, sizeof(TTLayoutTableCache));52if (ltc) {53int i;54for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {55ltc->entries[i].len = -1;56}57}58return ltc;59}6061static void freeCFontLayoutTableCache(TTLayoutTableCache* ltc) {62if (ltc) {63int i;64for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {65if(ltc->entries[i].ptr) free (ltc->entries[i].ptr);66}67if (ltc->kernPairs) free(ltc->kernPairs);68free(ltc);69}70}7172- (void) dealloc {73[fFont release];74fFont = nil;7576if (fNativeCGFont) {77CGFontRelease(fNativeCGFont);78fNativeCGFont = NULL;79if (layoutTableCache != NULL) {80freeCFontLayoutTableCache(layoutTableCache);81layoutTableCache = NULL;82}83}8485[super dealloc];86}8788- (void) finalize {89if (fNativeCGFont) {90CGFontRelease(fNativeCGFont);91fNativeCGFont = NULL;92}93if (layoutTableCache != NULL) {94freeCFontLayoutTableCache(layoutTableCache);95layoutTableCache = NULL;96}97[super finalize];98}99100static NSString* uiName = nil;101static NSString* uiBoldName = nil;102103+ (AWTFont *) awtFontForName:(NSString *)name104style:(int)style105{106// create font with family & size107NSFont *nsFont = nil;108109if ((uiName != nil && [name isEqualTo:uiName]) ||110(uiBoldName != nil && [name isEqualTo:uiBoldName])) {111if (style & java_awt_Font_BOLD) {112nsFont = [NSFont boldSystemFontOfSize:1.0];113} else {114nsFont = [NSFont systemFontOfSize:1.0];115}116#ifdef DEBUG117NSLog(@"nsFont-name is : %@", nsFont.familyName);118NSLog(@"nsFont-family is : %@", nsFont.fontName);119NSLog(@"nsFont-desc-name is : %@", nsFont.fontDescriptor.postscriptName);120#endif121122123} else {124nsFont = [NSFont fontWithName:name size:1.0];125}126127if (nsFont == nil) {128// if can't get font of that name, substitute system default font129nsFont = [NSFont fontWithName:@"Lucida Grande" size:1.0];130#ifdef DEBUG131NSLog(@"needed to substitute Lucida Grande for: %@", name);132#endif133}134135// create an italic style (if one is installed)136if (style & java_awt_Font_ITALIC) {137nsFont = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSItalicFontMask];138}139140// create a bold style (if one is installed)141if (style & java_awt_Font_BOLD) {142nsFont = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSBoldFontMask];143}144145return [[[AWTFont alloc] initWithFont:nsFont] autorelease];146}147148+ (NSFont *) nsFontForJavaFont:(jobject)javaFont env:(JNIEnv *)env {149if (javaFont == NULL) {150#ifdef DEBUG151NSLog(@"nil font");152#endif153return nil;154}155156static JNF_CLASS_CACHE(jc_Font, "java/awt/Font");157158// obtain the Font2D159static JNF_MEMBER_CACHE(jm_Font_getFont2D, jc_Font, "getFont2D", "()Lsun/font/Font2D;");160jobject font2d = JNFCallObjectMethod(env, javaFont, jm_Font_getFont2D);161if (font2d == NULL) {162#ifdef DEBUG163NSLog(@"nil font2d");164#endif165return nil;166}167168// if it's not a CFont, it's likely one of TTF or OTF fonts169// from the Sun rendering loops170static JNF_CLASS_CACHE(jc_CFont, "sun/font/CFont");171if (!JNFIsInstanceOf(env, font2d, &jc_CFont)) {172#ifdef DEBUG173NSLog(@"font2d !instanceof CFont");174#endif175return nil;176}177178static JNF_MEMBER_CACHE(jm_CFont_getFontStrike, jc_CFont, "getStrike", "(Ljava/awt/Font;)Lsun/font/FontStrike;");179jobject fontStrike = JNFCallObjectMethod(env, font2d, jm_CFont_getFontStrike, javaFont);180181static JNF_CLASS_CACHE(jc_CStrike, "sun/font/CStrike");182if (!JNFIsInstanceOf(env, fontStrike, &jc_CStrike)) {183#ifdef DEBUG184NSLog(@"fontStrike !instanceof CStrike");185#endif186return nil;187}188189static JNF_MEMBER_CACHE(jm_CStrike_nativeStrikePtr, jc_CStrike, "getNativeStrikePtr", "()J");190jlong awtStrikePtr = JNFCallLongMethod(env, fontStrike, jm_CStrike_nativeStrikePtr);191if (awtStrikePtr == 0L) {192#ifdef DEBUG193NSLog(@"nil nativeFontPtr from CFont");194#endif195return nil;196}197198AWTStrike *strike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);199200return [NSFont fontWithName:[strike->fAWTFont->fFont fontName] matrix:(CGFloat *)(&(strike->fAltTx))];201}202203@end204205206#pragma mark --- Font Discovery and Loading ---207208static NSArray* sFilteredFonts = nil;209static NSDictionary* sFontFamilyTable = nil;210211static NSString*212GetFamilyNameForFontName(NSString* fontname)213{214return [sFontFamilyTable objectForKey:fontname];215}216217static void addFont(CTFontUIFontType uiType,218NSMutableArray *allFonts,219NSMutableDictionary* fontFamilyTable) {220221CTFontRef font = CTFontCreateUIFontForLanguage(uiType, 0.0, NULL);222if (font == NULL) {223return;224}225CTFontDescriptorRef desc = CTFontCopyFontDescriptor(font);226if (desc == NULL) {227CFRelease(font);228return;229}230CFStringRef family = CTFontDescriptorCopyAttribute(desc, kCTFontFamilyNameAttribute);231if (family == NULL) {232CFRelease(desc);233CFRelease(font);234return;235}236CFStringRef name = CTFontDescriptorCopyAttribute(desc, kCTFontNameAttribute);237if (name == NULL) {238CFRelease(family);239CFRelease(desc);240CFRelease(font);241return;242}243if (uiType == kCTFontUIFontSystem) {244uiName = (NSString*)name;245}246if (uiType == kCTFontUIFontEmphasizedSystem) {247uiBoldName = (NSString*)name;248}249[allFonts addObject:name];250[fontFamilyTable setObject:family forKey:name];251#ifdef DEBUG252NSLog(@"name is : %@", (NSString*)name);253NSLog(@"family is : %@", (NSString*)family);254#endif255CFRelease(family);256CFRelease(name);257CFRelease(desc);258CFRelease(font);259}260261static NSArray*262GetFilteredFonts()263{264if (sFilteredFonts == nil) {265NSFontManager *fontManager = [NSFontManager sharedFontManager];266NSUInteger fontCount = [[fontManager availableFonts] count];267268NSMutableArray *allFonts = [[NSMutableArray alloc] initWithCapacity:fontCount];269NSMutableDictionary* fontFamilyTable = [[NSMutableDictionary alloc] initWithCapacity:fontCount];270NSArray *allFamilies = [fontManager availableFontFamilies];271272NSUInteger familyCount = [allFamilies count];273274NSUInteger familyIndex;275for (familyIndex = 0; familyIndex < familyCount; familyIndex++) {276NSString *family = [allFamilies objectAtIndex:familyIndex];277278if ((family == nil) || [family characterAtIndex:0] == '.') {279continue;280}281282NSArray *fontFaces = [fontManager availableMembersOfFontFamily:family];283NSUInteger faceCount = [fontFaces count];284285NSUInteger faceIndex;286for (faceIndex = 0; faceIndex < faceCount; faceIndex++) {287NSString* face = [[fontFaces objectAtIndex:faceIndex] objectAtIndex:0];288if (face != nil) {289[allFonts addObject:face];290[fontFamilyTable setObject:family forKey:face];291}292}293}294295/*296* JavaFX registers these fonts and so JDK needs to do so as well.297* If this isn't done we will have mis-matched rendering, since298* although these may include fonts that are enumerated normally299* they also demonstrably includes fonts that are not.300*/301addFont(kCTFontUIFontSystem, allFonts, fontFamilyTable);302addFont(kCTFontUIFontEmphasizedSystem, allFonts, fontFamilyTable);303304sFilteredFonts = allFonts;305sFontFamilyTable = fontFamilyTable;306}307308return sFilteredFonts;309}310311#pragma mark --- sun.font.CFontManager JNI ---312313static OSStatus CreateFSRef(FSRef *myFSRefPtr, NSString *inPath)314{315return FSPathMakeRef((UInt8 *)[inPath fileSystemRepresentation],316myFSRefPtr, NULL);317}318319// /*320// * Class: sun_font_CFontManager321// * Method: loadFileFont322// * Signature: (Ljava/lang/String;)Lsun/font/Font2D;323// */324// JNIEXPORT /* sun.font.CFont */ jobject JNICALL325// Java_sun_font_CFontManager_loadFileFont326// (JNIEnv *env, jclass obj, jstring fontpath)327// {328// jobject result = NULL;329//330// JNF_COCOA_ENTER(env);331//332// NSString *nsFilePath = JNFJavaToNSString(env, fontpath);333// jstring javaFontName = NULL;334//335// //336// // Note: This API uses ATS and can therefore return Carbon error codes.337// // These codes can be found at:338// // http://developer.apple.com/techpubs/macosx/Carbon/Files/FileManager/File_Manager/ResultCodes/ResultCodes.html339// //340//341// FSRef iFile;342// OSStatus status = CreateFSRef(&iFile, nsFilePath);343//344// if (status == noErr) {345// ATSFontContainerRef oContainer;346// status = ATSFontActivateFromFileReference(&iFile, kATSFontContextLocal,347// kATSFontFormatUnspecified,348// NULL,349// kATSOptionFlagsUseDataFork,350// &oContainer);351// if (status == noErr) {352// ATSFontRef ioArray[1];353// ItemCount oCount;354// status = ATSFontFindFromContainer(oContainer,355// kATSOptionFlagsUseDataFork,356// 1, ioArray, &oCount);357//358// if (status == noErr) {359// CFStringRef oName;360// status = ATSFontGetPostScriptName(ioArray[0],361// kATSOptionFlagsUseDataFork,362// &oName);363// if (status == noErr) {364// javaFontName = JNFNSToJavaString(env, (NSString *)oName);365// CFRelease(oName);366// }367// }368// }369// }370//371// if (javaFontName != NULL) {372// // create the CFont!373// static JNF_CLASS_CACHE(sjc_CFont, "sun/font/CFont");374// static JNF_CTOR_CACHE(sjf_CFont_ctor,375// sjc_CFont, "(Ljava/lang/String;)V");376// result = JNFNewObject(env, sjf_CFont_ctor, javaFontName);377// }378//379// JNF_COCOA_EXIT(env);380//381// return result;382// }383384/*385* Class: sun_font_CFontManager386* Method: loadNativeFonts387* Signature: ()V388*/389JNIEXPORT void JNICALL390Java_sun_font_CFontManager_loadNativeFonts391(JNIEnv *env, jobject jthis)392{393static JNF_CLASS_CACHE(jc_CFontManager,394"sun/font/CFontManager");395static JNF_MEMBER_CACHE(jm_registerFont, jc_CFontManager,396"registerFont",397"(Ljava/lang/String;Ljava/lang/String;)V");398399jint num = 0;400401JNF_COCOA_ENTER(env);402403NSArray *filteredFonts = GetFilteredFonts();404num = (jint)[filteredFonts count];405406jint i;407for (i = 0; i < num; i++) {408NSString *fontname = [filteredFonts objectAtIndex:i];409jobject jFontName = JNFNSToJavaString(env, fontname);410jobject jFontFamilyName =411JNFNSToJavaString(env, GetFamilyNameForFontName(fontname));412413JNFCallVoidMethod(env, jthis,414jm_registerFont, jFontName, jFontFamilyName);415}416417JNF_COCOA_EXIT(env);418}419420/*421* Class: Java_sun_font_CFontManager_loadNativeDirFonts422* Method: loadNativeDirFonts423* Signature: (Ljava/lang/String;)V;424*/425JNIEXPORT void JNICALL426Java_sun_font_CFontManager_loadNativeDirFonts427(JNIEnv *env, jclass clz, jstring filename)428{429JNF_COCOA_ENTER(env);430431NSString *nsFilePath = JNFJavaToNSString(env, filename);432433FSRef iFile;434OSStatus status = CreateFSRef(&iFile, nsFilePath);435436if (status == noErr) {437ATSFontContainerRef oContainer;438status = ATSFontActivateFromFileReference(&iFile, kATSFontContextLocal,439kATSFontFormatUnspecified,440NULL, kNilOptions,441&oContainer);442}443444JNF_COCOA_EXIT(env);445}446447#pragma mark --- sun.font.CFont JNI ---448449/*450* Class: sun_font_CFont451* Method: getPlatformFontPtrNative452* Signature: (JI)[B453*/454JNIEXPORT jlong JNICALL455Java_sun_font_CFont_getCGFontPtrNative456(JNIEnv *env, jclass clazz,457jlong awtFontPtr)458{459AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);460return (jlong)(awtFont->fNativeCGFont);461}462463/*464* Class: sun_font_CFont465* Method: getLayoutTableCacheNative466* Signature: (J)J467*/468JNIEXPORT jlong JNICALL469Java_sun_font_CFont_getLayoutTableCacheNative470(JNIEnv *env, jclass clazz,471jlong awtFontPtr)472{473AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);474if (awtFont->layoutTableCache == NULL) {475awtFont->layoutTableCache = newCFontLayoutTableCache();476}477return (jlong)(awtFont->layoutTableCache);478}479480/*481* Class: sun_font_CFont482* Method: getTableBytesNative483* Signature: (JI)[B484*/485JNIEXPORT jbyteArray JNICALL486Java_sun_font_CFont_getTableBytesNative487(JNIEnv *env, jclass clazz,488jlong awtFontPtr, jint jtag)489{490jbyteArray jbytes = NULL;491JNF_COCOA_ENTER(env);492493CTFontTableTag tag = (CTFontTableTag)jtag;494int i, found = 0;495AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);496NSFont* nsFont = awtFont->fFont;497CTFontRef ctfont = (CTFontRef)nsFont;498CFArrayRef tagsArray =499CTFontCopyAvailableTables(ctfont, kCTFontTableOptionNoOptions);500CFIndex numTags = CFArrayGetCount(tagsArray);501for (i=0; i<numTags; i++) {502if (tag ==503(CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tagsArray, i)) {504found = 1;505break;506}507}508CFRelease(tagsArray);509if (!found) {510return NULL;511}512CFDataRef table = CTFontCopyTable(ctfont, tag, kCTFontTableOptionNoOptions);513if (table == NULL) {514return NULL;515}516517char *tableBytes = (char*)(CFDataGetBytePtr(table));518size_t tableLength = CFDataGetLength(table);519if (tableBytes == NULL || tableLength == 0) {520CFRelease(table);521return NULL;522}523524jbytes = (*env)->NewByteArray(env, (jsize)tableLength);525if (jbytes == NULL) {526return NULL;527}528(*env)->SetByteArrayRegion(env, jbytes, 0,529(jsize)tableLength,530(jbyte*)tableBytes);531CFRelease(table);532533JNF_COCOA_EXIT(env);534535return jbytes;536}537538/*539* Class: sun_font_CFont540* Method: initNativeFont541* Signature: (Ljava/lang/String;I)J542*/543JNIEXPORT jlong JNICALL544Java_sun_font_CFont_createNativeFont545(JNIEnv *env, jclass clazz,546jstring nativeFontName, jint style)547{548AWTFont *awtFont = nil;549550JNF_COCOA_ENTER(env);551552awtFont =553[AWTFont awtFontForName:JNFJavaToNSString(env, nativeFontName)554style:style]; // autoreleased555556if (awtFont) {557CFRetain(awtFont); // GC558}559560JNF_COCOA_EXIT(env);561562return ptr_to_jlong(awtFont);563}564565/*566* Class: sun_font_CFont567* Method: getWidthNative568* Signature: (J)F569*/570JNIEXPORT jfloat JNICALL571Java_sun_font_CFont_getWidthNative572(JNIEnv *env, jobject cfont, jlong awtFontPtr)573{574float widthVal;575JNF_COCOA_ENTER(env);576577AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);578NSFont* nsFont = awtFont->fFont;579NSFontDescriptor *fontDescriptor = nsFont.fontDescriptor;580NSDictionary *fontTraits = [fontDescriptor objectForKey : NSFontTraitsAttribute];581NSNumber *width = [fontTraits objectForKey : NSFontWidthTrait];582widthVal = (float)[width floatValue];583584JNF_COCOA_EXIT(env);585return (jfloat)widthVal;586}587588/*589* Class: sun_font_CFont590* Method: getWeightNative591* Signature: (J)F592*/593JNIEXPORT jfloat JNICALL594Java_sun_font_CFont_getWeightNative595(JNIEnv *env, jobject cfont, jlong awtFontPtr)596{597float weightVal;598JNF_COCOA_ENTER(env);599600AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);601NSFont* nsFont = awtFont->fFont;602NSFontDescriptor *fontDescriptor = nsFont.fontDescriptor;603NSDictionary *fontTraits = [fontDescriptor objectForKey : NSFontTraitsAttribute];604NSNumber *weight = [fontTraits objectForKey : NSFontWeightTrait];605weightVal = (float)[weight floatValue];606607JNF_COCOA_EXIT(env);608return (jfloat)weightVal;609}610611/*612* Class: sun_font_CFont613* Method: disposeNativeFont614* Signature: (J)V615*/616JNIEXPORT void JNICALL617Java_sun_font_CFont_disposeNativeFont618(JNIEnv *env, jclass clazz, jlong awtFontPtr)619{620JNF_COCOA_ENTER(env);621622if (awtFontPtr) {623CFRelease((AWTFont *)jlong_to_ptr(awtFontPtr)); // GC624}625626JNF_COCOA_EXIT(env);627}628629630#pragma mark --- Miscellaneous JNI ---631632#ifndef HEADLESS633/*634* Class: sun_awt_PlatformFont635* Method: initIDs636* Signature: ()V637*/638JNIEXPORT void JNICALL639Java_sun_awt_PlatformFont_initIDs640(JNIEnv *env, jclass cls)641{642}643644/*645* Class: sun_awt_FontDescriptor646* Method: initIDs647* Signature: ()V648*/649JNIEXPORT void JNICALL650Java_sun_awt_FontDescriptor_initIDs651(JNIEnv *env, jclass cls)652{653}654#endif655656/*657* Class: sun_awt_FontDescriptor658* Method: initIDs659* Signature: ()V660*/661JNIEXPORT void JNICALL662Java_sun_font_CFont_getCascadeList663(JNIEnv *env, jclass cls, jlong awtFontPtr, jobject arrayListOfString)664{665jclass alc = (*env)->FindClass(env, "java/util/ArrayList");666if (alc == NULL) return;667jmethodID addMID = (*env)->GetMethodID(env, alc, "add", "(Ljava/lang/Object;)Z");668if (addMID == NULL) return;669670CFIndex i;671AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);672NSFont* nsFont = awtFont->fFont;673CTFontRef font = (CTFontRef)nsFont;674CFStringRef base = CTFontCopyFullName(font);675CFArrayRef codes = CFLocaleCopyISOLanguageCodes();676677#ifdef DEBUG678NSLog(@"BaseFont is : %@", (NSString*)base);679#endif680CFArrayRef fds = CTFontCopyDefaultCascadeListForLanguages(font, codes);681CFIndex cnt = CFArrayGetCount(fds);682for (i=0; i<cnt; i++) {683CTFontDescriptorRef ref = CFArrayGetValueAtIndex(fds, i);684CFStringRef fontname =685CTFontDescriptorCopyAttribute(ref, kCTFontNameAttribute);686#ifdef DEBUG687NSLog(@"Font is : %@", (NSString*)fontname);688#endif689jstring jFontName = (jstring)JNFNSToJavaString(env, fontname);690(*env)->CallBooleanMethod(env, arrayListOfString, addMID, jFontName);691(*env)->DeleteLocalRef(env, jFontName);692}693}694#endif695696697