annotate modules/javafx.graphics/src/main/native-font/MacFontFinder.c @ 11306:c91a28ed4845

8223760: support static builds Reviewed-by: kcr
author jvos
date Wed, 17 Jul 2019 22:22:20 +0200
parents 77bfbbf9a00c
children e21afe5aabed
rev   line source
kcr@4019 1 /*
kcr@10361 2 * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
kcr@4019 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
kcr@4019 4 *
kcr@4019 5 * This code is free software; you can redistribute it and/or modify it
kcr@4019 6 * under the terms of the GNU General Public License version 2 only, as
kcr@4019 7 * published by the Free Software Foundation. Oracle designates this
kcr@4019 8 * particular file as subject to the "Classpath" exception as provided
kcr@4019 9 * by Oracle in the LICENSE file that accompanied this code.
kcr@4019 10 *
kcr@4019 11 * This code is distributed in the hope that it will be useful, but WITHOUT
kcr@4019 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
kcr@4019 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kcr@4019 14 * version 2 for more details (a copy is included in the LICENSE file that
kcr@4019 15 * accompanied this code).
kcr@4019 16 *
kcr@4019 17 * You should have received a copy of the GNU General Public License version
kcr@4019 18 * 2 along with this work; if not, write to the Free Software Foundation,
kcr@4019 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
kcr@4019 20 *
kcr@4019 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
kcr@4019 22 * or visit www.oracle.com if you need additional information or have any
kcr@4019 23 * questions.
kcr@4019 24 */
kcr@4019 25
kcr@4019 26 #ifdef __APPLE__
kcr@4019 27
kcr@4019 28 #include <TargetConditionals.h>
kcr@4019 29
kcr@4019 30 #include <jni.h>
kcr@4019 31 #include <com_sun_javafx_font_MacFontFinder.h>
kcr@4019 32
jvos@11306 33 #if TARGET_OS_IPHONE || defined(STATIC_BUILD) /* iOS or static build */
kcr@4019 34
kcr@4019 35 #import <CoreText/CoreText.h>
kcr@4019 36
kcr@4019 37 JNIEXPORT jint JNICALL
kcr@4019 38 JNI_OnLoad_javafx_font(JavaVM * vm, void * reserved) {
kcr@4019 39 #ifdef JNI_VERSION_1_8
kcr@4019 40 //min. returned JNI_VERSION required by JDK8 for builtin libraries
kcr@4019 41 JNIEnv *env;
kcr@4019 42 if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_8) != JNI_OK) {
kcr@4019 43 return JNI_VERSION_1_4;
kcr@4019 44 }
kcr@4019 45 return JNI_VERSION_1_8;
kcr@4019 46 #else
kcr@4019 47 return JNI_VERSION_1_4;
kcr@4019 48 #endif
kcr@4019 49 }
kcr@4019 50
kcr@4019 51 #else /* MAC OS X */
kcr@4019 52
kcr@4019 53 #import <CoreFoundation/CoreFoundation.h>
kcr@4019 54 #import <ApplicationServices/ApplicationServices.h>
kcr@4019 55
kcr@4019 56 #endif
kcr@4019 57
chien@6892 58 extern jboolean checkAndClearException(JNIEnv *env);
kcr@4019 59
kcr@4019 60 jstring createJavaString(JNIEnv *env, CFStringRef stringRef)
kcr@4019 61 {
kcr@4019 62 CFIndex length = CFStringGetLength(stringRef);
kcr@4019 63 UniChar buffer[length];
kcr@4019 64 CFStringGetCharacters(stringRef, CFRangeMake(0, length), buffer);
chien@6892 65 jstring jStr = (*env)->NewString(env, (jchar *)buffer, length);
chien@6892 66 if (checkAndClearException(env) || !jStr) {
chien@6892 67 fprintf(stderr, "createJavaString error: JNI exception or jStr == NULL");
chien@6892 68 return NULL;
chien@6892 69 }
chien@6892 70 return jStr;
kcr@4019 71 }
kcr@4019 72
kcr@4019 73 /*
kcr@4019 74 * Class: com_sun_javafx_font_MacFontFinder
kcr@4019 75 * Method: getSystemFontSize
kcr@4019 76 * Signature: ()F
kcr@4019 77 */
kcr@4019 78 JNIEXPORT jfloat JNICALL Java_com_sun_javafx_font_MacFontFinder_getSystemFontSize
kcr@4019 79 (JNIEnv *env, jclass obj)
kcr@4019 80 {
kcr@4019 81 CTFontRef font = CTFontCreateUIFontForLanguage(
kcr@9542 82 kCTFontSystemFontType,
kcr@4019 83 0.0, //get system font with default size
kcr@4019 84 NULL);
kcr@4019 85 jfloat systemFontDefaultSize = (jfloat) CTFontGetSize (font);
kcr@4019 86 CFRelease(font);
kcr@4019 87 return systemFontDefaultSize;
kcr@4019 88 }
kcr@4019 89
kcr@4019 90 /*
kcr@4019 91 * Class: com_sun_javafx_font_MacFontFinder
kcr@4019 92 * Method: getFont
kcr@4019 93 * Signature: (I)Ljava/lang/String;
kcr@4019 94 */
kcr@4019 95 JNIEXPORT jstring JNICALL Java_com_sun_javafx_font_MacFontFinder_getFont
kcr@4019 96 (JNIEnv *env, jclass obj, jint type)
kcr@4019 97 {
kcr@4019 98 CTFontRef font = CTFontCreateUIFontForLanguage(type, 0, NULL);
kcr@4019 99 CFStringRef family = CTFontCopyFamilyName(font);
kcr@4019 100 jstring jfamily = createJavaString(env, family);
kcr@4019 101 CFRelease(family);
kcr@4019 102 CFRelease(font);
kcr@4019 103 return jfamily;
kcr@4019 104 }
kcr@4019 105
felipe@5770 106 CFIndex addCTFontDescriptor(CTFontDescriptorRef fd, JNIEnv *env, jobjectArray result, CFIndex index)
felipe@5770 107 {
felipe@5770 108 if (fd) {
felipe@5770 109 CFStringRef name = CTFontDescriptorCopyAttribute(fd, kCTFontDisplayNameAttribute);
felipe@5770 110 CFStringRef family = CTFontDescriptorCopyAttribute(fd, kCTFontFamilyNameAttribute);
felipe@5770 111 CFURLRef url = CTFontDescriptorCopyAttribute(fd, kCTFontURLAttribute);
felipe@5770 112 CFStringRef file = url ? CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle) : NULL;
felipe@5770 113 if (name && family && file) {
felipe@5770 114 jstring jname = createJavaString(env, name);
felipe@5770 115 jstring jfamily = createJavaString(env, family);
felipe@5770 116 jstring jfile = createJavaString(env, file);
chien@6892 117 if (jname && jfamily && jfile) {
chien@6892 118 (*env)->SetObjectArrayElement(env, result, index++, jname);
chien@6892 119 checkAndClearException(env);
chien@6892 120 (*env)->SetObjectArrayElement(env, result, index++, jfamily);
chien@6892 121 checkAndClearException(env);
chien@6892 122 (*env)->SetObjectArrayElement(env, result, index++, jfile);
chien@6892 123 checkAndClearException(env);
ckyang@10118 124 (*env)->DeleteLocalRef(env, jname);
ckyang@10118 125 (*env)->DeleteLocalRef(env, jfamily);
ckyang@10118 126 (*env)->DeleteLocalRef(env, jfile);
chien@6892 127 }
felipe@5770 128 }
felipe@5770 129 if (name) CFRelease(name);
felipe@5770 130 if (family) CFRelease(family);
felipe@5770 131 if (url) CFRelease(url);
felipe@5770 132 if (file) CFRelease(file);
felipe@5770 133 }
felipe@5770 134 return index;
felipe@5770 135 }
felipe@5770 136
kcr@4019 137 /*
kcr@4019 138 * Class: com_sun_javafx_font_MacFontFinder
kcr@4019 139 * Method: getFontData
kcr@4019 140 * Signature: ()[Ljava/lang/String;
kcr@4019 141 */
kcr@4019 142 JNIEXPORT jobjectArray JNICALL Java_com_sun_javafx_font_MacFontFinder_getFontData
kcr@4019 143 (JNIEnv *env, jclass obj)
kcr@4019 144 {
kcr@4019 145 /* No caching as this method is only invoked once */
kcr@4019 146 jclass jStringClass = (*env)->FindClass(env, "java/lang/String");
chien@6892 147 if (checkAndClearException(env) || !jStringClass) {
chien@6892 148 fprintf(stderr, "getFontData error: JNI exception or jStringClass == NULL");
chien@6892 149 return NULL;
chien@6892 150 }
kcr@4019 151
kcr@4019 152 CTFontCollectionRef collection = CTFontCollectionCreateFromAvailableFonts(NULL);
kcr@4019 153 CFArrayRef fonts = CTFontCollectionCreateMatchingFontDescriptors(collection);
kcr@4019 154 CFRelease(collection);
kcr@4019 155
kcr@4019 156 CFIndex count = CFArrayGetCount(fonts);
felipe@5770 157 jobjectArray result = (*env)->NewObjectArray(env, (count + 2) * 3, jStringClass, NULL);
chien@6892 158 if (checkAndClearException(env) || !result) {
chien@6892 159 fprintf(stderr, "getFontData error: JNI exception or result == NULL");
kcr@4019 160 /* out of memory */
kcr@4019 161 CFRelease(fonts);
kcr@4019 162 return NULL;
kcr@4019 163 }
kcr@4019 164
kcr@4019 165 CFIndex i = 0, j = 0;
kcr@4019 166 while (i < count) {
kcr@4019 167 CTFontDescriptorRef fd = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i++);
felipe@5770 168 j = addCTFontDescriptor(fd, env, result, j);
kcr@4019 169 }
kcr@4019 170 CFRelease(fonts);
felipe@5770 171
felipe@5770 172 /* Sometimes a font name starting with dot (internal font, e.g. ".Helvetica NeueUI")
felipe@5770 173 * is returned as a system UI font, but such font is not available in the collection
felipe@5770 174 * of available fonts. Thus, it is safer to always add the system font manually
felipe@5770 175 * to the list so JavaFX can find it. If the UI font is added twice it gets
felipe@5770 176 * handled in Java.
felipe@5770 177 */
felipe@5770 178 CTFontRef font = CTFontCreateUIFontForLanguage(kCTFontSystemFontType, 0, NULL);
felipe@5770 179 CTFontDescriptorRef fd = CTFontCopyFontDescriptor(font);
felipe@5770 180 j = addCTFontDescriptor(fd, env, result, j);
felipe@5770 181 CFRelease(fd);
felipe@5770 182 CFRelease(font);
felipe@5770 183
felipe@5770 184 /* Also add the EmphasizedSystemFont as it might make the bold version
felipe@5770 185 * for the system font available to JavaFX.
felipe@5770 186 */
felipe@5770 187 font = CTFontCreateUIFontForLanguage(kCTFontEmphasizedSystemFontType, 0, NULL);
felipe@5770 188 fd = CTFontCopyFontDescriptor(font);
felipe@5770 189 j = addCTFontDescriptor(fd, env, result, j);
felipe@5770 190 CFRelease(fd);
felipe@5770 191 CFRelease(font);
felipe@5770 192
kcr@4019 193 return result;
kcr@4019 194 }
kcr@4019 195
kcr@4019 196 #endif /* __APPLE__ */