From 7d38d5643e039726981df69367a7faeec4a0dbb9 Mon Sep 17 00:00:00 2001 From: linyuxuan Date: Fri, 5 Jan 2024 10:28:06 +0800 Subject: [PATCH 1/4] Optimizes how information is retrieved from fontconfig The original getFontConfig function contains two parts: obtaining fontconfig information and obtaining matching font list, which are now split into two functions for reuse. --- .../unix/native/common/awt/fontpath.c | 151 ++++++++++-------- 1 file changed, 84 insertions(+), 67 deletions(-) diff --git a/src/java.desktop/unix/native/common/awt/fontpath.c b/src/java.desktop/unix/native/common/awt/fontpath.c index b270a3fc94d..21d73f1d968 100644 --- a/src/java.desktop/unix/native/common/awt/fontpath.c +++ b/src/java.desktop/unix/native/common/awt/fontpath.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -790,15 +790,92 @@ Java_sun_font_FontConfigManager_getFontConfigVersion JNIEXPORT void JNICALL -Java_sun_font_FontConfigManager_getFontConfig -(JNIEnv *env, jclass obj, jstring localeStr, jobject fcInfoObj, - jobjectArray fcCompFontArray, jboolean includeFallbacks) { +Java_sun_font_FontConfigManager_getFontConfigInfo(JNIEnv *env, jclass obj, jobject fcInfoObj) { + FcGetVersionFuncType FcGetVersion; + FcConfigGetCacheDirsFuncType FcConfigGetCacheDirs; + FcStrListNextFuncType FcStrListNext; + FcStrListDoneFuncType FcStrListDone; + + jstring jstr; + void *libfontconfig; + jfieldID fcVersionID, fcCacheDirsID; + jclass fcInfoClass; + + CHECK_NULL(fcInfoObj); + + fcInfoClass = + (*env)->FindClass(env, "sun/font/FontConfigManager$FontConfigInfo"); + CHECK_NULL(fcInfoClass); + + CHECK_NULL(fcVersionID = (*env)->GetFieldID(env, fcInfoClass, "fcVersion", "I")); + CHECK_NULL(fcCacheDirsID = (*env)->GetFieldID(env, fcInfoClass, "cacheDirs", + "[Ljava/lang/String;")); + + if ((libfontconfig = openFontConfig()) == NULL) { + return; + } + + FcGetVersion = (FcGetVersionFuncType)dlsym(libfontconfig, "FcGetVersion"); + + if (FcGetVersion == NULL) {/* problem with the library: return.*/ + closeFontConfig(libfontconfig, JNI_FALSE); + return; + } + (*env)->SetIntField(env, fcInfoObj, fcVersionID, (*FcGetVersion)()); + + /* Optionally get the cache dir locations. This isn't + * available until v 2.4.x, but this is OK since on those later versions + * we can check the time stamps on the cache dirs to see if we + * are out of date. There are a couple of assumptions here. First + * that the time stamp on the directory changes when the contents are + * updated. Secondly that the locations don't change. The latter is + * most likely if a new version of fontconfig is installed, but we also + * invalidate the cache if we detect that. Arguably even that is "rare", + * and most likely is tied to an OS upgrade which gets a new file anyway. + */ + FcConfigGetCacheDirs = + (FcConfigGetCacheDirsFuncType)dlsym(libfontconfig, + "FcConfigGetCacheDirs"); + FcStrListNext = + (FcStrListNextFuncType)dlsym(libfontconfig, "FcStrListNext"); + FcStrListDone = + (FcStrListDoneFuncType)dlsym(libfontconfig, "FcStrListDone"); + if (FcStrListNext != NULL && FcStrListDone != NULL && + FcConfigGetCacheDirs != NULL) { + FcStrList* cacheDirs; + FcChar8* cacheDir; + int cnt = 0; + jobject cacheDirArray = + (*env)->GetObjectField(env, fcInfoObj, fcCacheDirsID); + int max = (*env)->GetArrayLength(env, cacheDirArray); + + cacheDirs = (*FcConfigGetCacheDirs)(NULL); + if (cacheDirs != NULL) { + while ((cnt < max) && (cacheDir = (*FcStrListNext)(cacheDirs))) { + jstr = (*env)->NewStringUTF(env, (const char*)cacheDir); + if (IS_NULL(jstr)) { + (*FcStrListDone)(cacheDirs); + return; + } + (*env)->SetObjectArrayElement(env, cacheDirArray, cnt++, jstr); + (*env)->DeleteLocalRef(env, jstr); + } + (*FcStrListDone)(cacheDirs); + } + } + /*close the ".so" */ + closeFontConfig(libfontconfig, JNI_TRUE); +} + +JNIEXPORT void JNICALL +Java_sun_font_FontConfigManager_getFontConfigMatch(JNIEnv *env, jclass obj, + jstring localeStr, jobject fcCompFontArray, + jboolean includeFallbacks) { FcNameParseFuncType FcNameParse; FcPatternAddStringFuncType FcPatternAddString; FcConfigSubstituteFuncType FcConfigSubstitute; FcDefaultSubstituteFuncType FcDefaultSubstitute; - FcFontMatchFuncType FcFontMatch; FcPatternGetStringFuncType FcPatternGetString; FcPatternDestroyFuncType FcPatternDestroy; FcPatternGetCharSetFuncType FcPatternGetCharSet; @@ -807,10 +884,6 @@ Java_sun_font_FontConfigManager_getFontConfig FcCharSetUnionFuncType FcCharSetUnion; FcCharSetDestroyFuncType FcCharSetDestroy; FcCharSetSubtractCountFuncType FcCharSetSubtractCount; - FcGetVersionFuncType FcGetVersion; - FcConfigGetCacheDirsFuncType FcConfigGetCacheDirs; - FcStrListNextFuncType FcStrListNext; - FcStrListDoneFuncType FcStrListDone; int i, arrlen; jobject fcCompFontObj; @@ -819,20 +892,15 @@ Java_sun_font_FontConfigManager_getFontConfig FcPattern *pattern; FcResult result; void* libfontconfig; - jfieldID fcNameID, fcFirstFontID, fcAllFontsID, fcVersionID, fcCacheDirsID; + jfieldID fcNameID, fcFirstFontID, fcAllFontsID; jfieldID familyNameID, styleNameID, fullNameID, fontFileID; jmethodID fcFontCons; char* debugMinGlyphsStr = getenv("J2D_DEBUG_MIN_GLYPHS"); - jclass fcInfoClass; jclass fcCompFontClass; jclass fcFontClass; - CHECK_NULL(fcInfoObj); CHECK_NULL(fcCompFontArray); - fcInfoClass = - (*env)->FindClass(env, "sun/font/FontConfigManager$FontConfigInfo"); - CHECK_NULL(fcInfoClass); fcCompFontClass = (*env)->FindClass(env, "sun/font/FontConfigManager$FcCompFont"); CHECK_NULL(fcCompFontClass); @@ -841,9 +909,6 @@ Java_sun_font_FontConfigManager_getFontConfig CHECK_NULL(fcFontClass); - CHECK_NULL(fcVersionID = (*env)->GetFieldID(env, fcInfoClass, "fcVersion", "I")); - CHECK_NULL(fcCacheDirsID = (*env)->GetFieldID(env, fcInfoClass, "cacheDirs", - "[Ljava/lang/String;")); CHECK_NULL(fcNameID = (*env)->GetFieldID(env, fcCompFontClass, "fcName", "Ljava/lang/String;")); CHECK_NULL(fcFirstFontID = (*env)->GetFieldID(env, fcCompFontClass, "firstFont", @@ -871,7 +936,6 @@ Java_sun_font_FontConfigManager_getFontConfig (FcConfigSubstituteFuncType)dlsym(libfontconfig, "FcConfigSubstitute"); FcDefaultSubstitute = (FcDefaultSubstituteFuncType) dlsym(libfontconfig, "FcDefaultSubstitute"); - FcFontMatch = (FcFontMatchFuncType)dlsym(libfontconfig, "FcFontMatch"); FcPatternGetString = (FcPatternGetStringFuncType)dlsym(libfontconfig, "FcPatternGetString"); FcPatternDestroy = @@ -890,69 +954,23 @@ Java_sun_font_FontConfigManager_getFontConfig FcCharSetSubtractCount = (FcCharSetSubtractCountFuncType)dlsym(libfontconfig, "FcCharSetSubtractCount"); - FcGetVersion = (FcGetVersionFuncType)dlsym(libfontconfig, "FcGetVersion"); if (FcNameParse == NULL || FcPatternAddString == NULL || FcConfigSubstitute == NULL || FcDefaultSubstitute == NULL || - FcFontMatch == NULL || FcPatternGetString == NULL || FcPatternDestroy == NULL || FcPatternGetCharSet == NULL || + FcFontSort == NULL || FcFontSetDestroy == NULL || FcCharSetUnion == NULL || FcCharSetDestroy == NULL || - FcGetVersion == NULL || FcCharSetSubtractCount == NULL) {/* problem with the library: return.*/ closeFontConfig(libfontconfig, JNI_FALSE); return; } - (*env)->SetIntField(env, fcInfoObj, fcVersionID, (*FcGetVersion)()); - - /* Optionally get the cache dir locations. This isn't - * available until v 2.4.x, but this is OK since on those later versions - * we can check the time stamps on the cache dirs to see if we - * are out of date. There are a couple of assumptions here. First - * that the time stamp on the directory changes when the contents are - * updated. Secondly that the locations don't change. The latter is - * most likely if a new version of fontconfig is installed, but we also - * invalidate the cache if we detect that. Arguably even that is "rare", - * and most likely is tied to an OS upgrade which gets a new file anyway. - */ - FcConfigGetCacheDirs = - (FcConfigGetCacheDirsFuncType)dlsym(libfontconfig, - "FcConfigGetCacheDirs"); - FcStrListNext = - (FcStrListNextFuncType)dlsym(libfontconfig, "FcStrListNext"); - FcStrListDone = - (FcStrListDoneFuncType)dlsym(libfontconfig, "FcStrListDone"); - if (FcStrListNext != NULL && FcStrListDone != NULL && - FcConfigGetCacheDirs != NULL) { - - FcStrList* cacheDirs; - FcChar8* cacheDir; - int cnt = 0; - jobject cacheDirArray = - (*env)->GetObjectField(env, fcInfoObj, fcCacheDirsID); - int max = (*env)->GetArrayLength(env, cacheDirArray); - - cacheDirs = (*FcConfigGetCacheDirs)(NULL); - if (cacheDirs != NULL) { - while ((cnt < max) && (cacheDir = (*FcStrListNext)(cacheDirs))) { - jstr = (*env)->NewStringUTF(env, (const char*)cacheDir); - if (IS_NULL(jstr)) { - (*FcStrListDone)(cacheDirs); - return; - } - (*env)->SetObjectArrayElement(env, cacheDirArray, cnt++, jstr); - (*env)->DeleteLocalRef(env, jstr); - } - (*FcStrListDone)(cacheDirs); - } - } - locale = (*env)->GetStringUTFChars(env, localeStr, 0); if (locale == NULL) { (*env)->ExceptionClear(env); @@ -1214,7 +1232,6 @@ Java_sun_font_FontConfigManager_getFontConfig } /* release resources and close the ".so" */ - if (locale) { (*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale); } -- 2.39.2