From 7d38d5643e039726981df69367a7faeec4a0dbb9 Mon Sep 17 00:00:00 2001
From: linyuxuan <linyuxuan@kylinos.cn>
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

