1 /*
2 * Copyright (c) 1998, 2018, 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
870 FcPatternDestroyFuncType FcPatternDestroy;
871
872 FcPattern *pattern, *matchPattern;
873 FcResult result;
874 FcBool antialias = FcFalse;
875 int rgba = 0;
876 const char *locale=NULL, *fcName=NULL;
877 void* libfontconfig;
878
879 if (fcNameStr == NULL || localeStr == NULL) {
880 return -1;
881 }
882
883 fcName = (*env)->GetStringUTFChars(env, fcNameStr, 0);
884 if (fcName == NULL) {
885 return -1;
886 }
887 locale = (*env)->GetStringUTFChars(env, localeStr, 0);
888
889 if ((libfontconfig = openFontConfig()) == NULL) {
890 (*env)->ReleaseStringUTFChars (env, fcNameStr, (const char*)fcName);
891 if (locale) {
892 (*env)->ReleaseStringUTFChars (env, localeStr,(const char*)locale);
893 }
894 return -1;
895 }
896
897 FcNameParse = (FcNameParseFuncType)dlsym(libfontconfig, "FcNameParse");
898 FcPatternAddString =
899 (FcPatternAddStringFuncType)dlsym(libfontconfig, "FcPatternAddString");
900 FcConfigSubstitute =
901 (FcConfigSubstituteFuncType)dlsym(libfontconfig, "FcConfigSubstitute");
902 FcDefaultSubstitute = (FcDefaultSubstituteFuncType)
903 dlsym(libfontconfig, "FcDefaultSubstitute");
904 FcFontMatch = (FcFontMatchFuncType)dlsym(libfontconfig, "FcFontMatch");
905 FcPatternGetBool = (FcPatternGetBoolFuncType)
906 dlsym(libfontconfig, "FcPatternGetBool");
907 FcPatternGetInteger = (FcPatternGetIntegerFuncType)
908 dlsym(libfontconfig, "FcPatternGetInteger");
909 FcPatternDestroy =
910 (FcPatternDestroyFuncType)dlsym(libfontconfig, "FcPatternDestroy");
911
912 if (FcNameParse == NULL ||
913 FcPatternAddString == NULL ||
914 FcConfigSubstitute == NULL ||
915 FcDefaultSubstitute == NULL ||
916 FcFontMatch == NULL ||
917 FcPatternGetBool == NULL ||
918 FcPatternGetInteger == NULL ||
919 FcPatternDestroy == NULL) { /* problem with the library: return. */
920
921 (*env)->ReleaseStringUTFChars (env, fcNameStr, (const char*)fcName);
922 if (locale) {
923 (*env)->ReleaseStringUTFChars (env, localeStr,(const char*)locale);
924 }
925 closeFontConfig(libfontconfig, JNI_FALSE);
926 return -1;
927 }
928
929
930 pattern = (*FcNameParse)((FcChar8 *)fcName);
931 if (locale != NULL) {
932 (*FcPatternAddString)(pattern, FC_LANG, (unsigned char*)locale);
933 }
934 (*FcConfigSubstitute)(NULL, pattern, FcMatchPattern);
935 (*FcDefaultSubstitute)(pattern);
936 matchPattern = (*FcFontMatch)(NULL, pattern, &result);
937 /* Perhaps should call FcFontRenderPrepare() here as some pattern
938 * elements might change as a result of that call, but I'm not seeing
939 * any difference in testing.
940 */
941 if (matchPattern) {
942 (*FcPatternGetBool)(matchPattern, FC_ANTIALIAS, 0, &antialias);
943 (*FcPatternGetInteger)(matchPattern, FC_RGBA, 0, &rgba);
944 (*FcPatternDestroy)(matchPattern);
945 }
946 (*FcPatternDestroy)(pattern);
947
948 (*env)->ReleaseStringUTFChars (env, fcNameStr, (const char*)fcName);
949 if (locale) {
950 (*env)->ReleaseStringUTFChars (env, localeStr, (const char*)locale);
951 }
952 closeFontConfig(libfontconfig, JNI_TRUE);
953
954 if (antialias == FcFalse) {
955 return TEXT_AA_OFF;
956 } else if (rgba <= FC_RGBA_UNKNOWN || rgba >= FC_RGBA_NONE) {
957 return TEXT_AA_ON;
958 } else {
959 switch (rgba) {
960 case FC_RGBA_RGB : return TEXT_AA_LCD_HRGB;
961 case FC_RGBA_BGR : return TEXT_AA_LCD_HBGR;
962 case FC_RGBA_VRGB : return TEXT_AA_LCD_VRGB;
963 case FC_RGBA_VBGR : return TEXT_AA_LCD_VBGR;
964 default : return TEXT_AA_LCD_HRGB; // should not get here.
965 }
966 }
967 }
968
969 JNIEXPORT jint JNICALL
970 Java_sun_font_FontConfigManager_getFontConfigVersion
1162 int fn, j, fontCount, nfonts;
1163 unsigned int minGlyphs;
1164 FcChar8 **family, **styleStr, **fullname, **file;
1165 jarray fcFontArr = NULL;
1166 FcCharSet *unionCharset = NULL;
1167
1168 fcCompFontObj = (*env)->GetObjectArrayElement(env, fcCompFontArray, i);
1169 fcNameStr =
1170 (jstring)((*env)->GetObjectField(env, fcCompFontObj, fcNameID));
1171 fcName = (*env)->GetStringUTFChars(env, fcNameStr, 0);
1172 if (fcName == NULL) {
1173 (*env)->DeleteLocalRef(env, fcCompFontObj);
1174 (*env)->DeleteLocalRef(env, fcNameStr);
1175 continue;
1176 }
1177 pattern = (*FcNameParse)((FcChar8 *)fcName);
1178 (*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
1179 (*env)->DeleteLocalRef(env, fcNameStr);
1180 if (pattern == NULL) {
1181 closeFontConfig(libfontconfig, JNI_FALSE);
1182 return;
1183 }
1184
1185 /* locale may not usually be necessary as fontconfig appears to apply
1186 * this anyway based on the user's environment. However we want
1187 * to use the value of the JDK startup locale so this should take
1188 * care of it.
1189 */
1190 if (locale != NULL) {
1191 (*FcPatternAddString)(pattern, FC_LANG, (unsigned char*)locale);
1192 }
1193 (*FcConfigSubstitute)(NULL, pattern, FcMatchPattern);
1194 (*FcDefaultSubstitute)(pattern);
1195 fontset = (*FcFontSort)(NULL, pattern, FcTrue, NULL, &result);
1196 if (fontset == NULL) {
1197 (*FcPatternDestroy)(pattern);
1198 closeFontConfig(libfontconfig, JNI_FALSE);
1199 return;
1200 }
1201
1202 /* fontconfig returned us "nfonts". If we are just getting the
1203 * first font, we set nfont to zero. Otherwise we use "nfonts".
1204 * Next create separate C arrrays of length nfonts for family file etc.
1205 * Inspect the returned fonts and the ones we like (adds enough glyphs)
1206 * are added to the arrays and we increment 'fontCount'.
1207 */
1208 nfonts = fontset->nfont;
1209 family = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
1210 styleStr = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
1211 fullname = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
1212 file = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
1213 if (family == NULL || styleStr == NULL ||
1214 fullname == NULL || file == NULL) {
1215 if (family != NULL) {
1216 free(family);
1217 }
1218 if (styleStr != NULL) {
1219 free(styleStr);
1220 }
1221 if (fullname != NULL) {
1222 free(fullname);
1223 }
1224 if (file != NULL) {
1225 free(file);
1226 }
1227 (*FcPatternDestroy)(pattern);
1228 (*FcFontSetDestroy)(fontset);
1229 closeFontConfig(libfontconfig, JNI_FALSE);
1230 return;
1231 }
1232 fontCount = 0;
1233 minGlyphs = 20;
1234 if (debugMinGlyphsStr != NULL) {
1235 int val = minGlyphs;
1236 sscanf(debugMinGlyphsStr, "%5d", &val);
1237 if (val >= 0 && val <= 65536) {
1238 minGlyphs = val;
1239 }
1240 }
1241
1242 for (j=0; j<nfonts; j++) {
1243 FcPattern *fontPattern = fontset->fonts[j];
1244 FcChar8 *fontformat;
1245 FcCharSet *charset = NULL;
1246
1247 fontformat = NULL;
1248 (*FcPatternGetString)(fontPattern, FC_FONTFORMAT, 0, &fontformat);
1249 /* We only want TrueType fonts but some Linuxes still depend
1252 */
1253 if (fontformat != NULL
1254 && (strcmp((char*)fontformat, "TrueType") != 0)
1255 #if defined(__linux__) || defined(_AIX)
1256 && (strcmp((char*)fontformat, "Type 1") != 0)
1257 && (strcmp((char*)fontformat, "CFF") != 0)
1258 #endif
1259 ) {
1260 continue;
1261 }
1262 result = (*FcPatternGetCharSet)(fontPattern,
1263 FC_CHARSET, 0, &charset);
1264 if (result != FcResultMatch) {
1265 free(family);
1266 free(fullname);
1267 free(styleStr);
1268 free(file);
1269 (*FcPatternDestroy)(pattern);
1270 (*FcFontSetDestroy)(fontset);
1271 closeFontConfig(libfontconfig, JNI_FALSE);
1272 return;
1273 }
1274
1275 /* We don't want 20 or 30 fonts, so once we hit 10 fonts,
1276 * then require that they really be adding value. Too many
1277 * adversely affects load time for minimal value-add.
1278 * This is still likely far more than we've had in the past.
1279 */
1280 if (j==10) {
1281 minGlyphs = 50;
1282 }
1283 if (unionCharset == NULL) {
1284 unionCharset = charset;
1285 } else {
1286 if ((*FcCharSetSubtractCount)(charset, unionCharset)
1287 > minGlyphs) {
1288 unionCharset = (* FcCharSetUnion)(unionCharset, charset);
1289 } else {
1290 continue;
1291 }
1306
1307 /* Once we get here 'fontCount' is the number of returned fonts
1308 * we actually want to use, so we create 'fcFontArr' of that length.
1309 * The non-null entries of "family[]" etc are those fonts.
1310 * Then loop again over all nfonts adding just those non-null ones
1311 * to 'fcFontArr'. If its null (we didn't want the font)
1312 * then we don't enter the main body.
1313 * So we should never get more than 'fontCount' entries.
1314 */
1315 if (includeFallbacks) {
1316 fcFontArr =
1317 (*env)->NewObjectArray(env, fontCount, fcFontClass, NULL);
1318 if (IS_NULL(fcFontArr)) {
1319 free(family);
1320 free(fullname);
1321 free(styleStr);
1322 free(file);
1323 (*FcPatternDestroy)(pattern);
1324 (*FcFontSetDestroy)(fontset);
1325 closeFontConfig(libfontconfig, JNI_FALSE);
1326 return;
1327 }
1328 (*env)->SetObjectField(env,fcCompFontObj, fcAllFontsID, fcFontArr);
1329 }
1330 fn=0;
1331
1332 for (j=0;j<nfonts;j++) {
1333 if (family[j] != NULL) {
1334 jobject fcFont =
1335 (*env)->NewObject(env, fcFontClass, fcFontCons);
1336 if (IS_NULL(fcFont)) break;
1337 jstr = (*env)->NewStringUTF(env, (const char*)family[j]);
1338 if (IS_NULL(jstr)) break;
1339 (*env)->SetObjectField(env, fcFont, familyNameID, jstr);
1340 (*env)->DeleteLocalRef(env, jstr);
1341 if (file[j] != NULL) {
1342 jstr = (*env)->NewStringUTF(env, (const char*)file[j]);
1343 if (IS_NULL(jstr)) break;
1344 (*env)->SetObjectField(env, fcFont, fontFileID, jstr);
1345 (*env)->DeleteLocalRef(env, jstr);
1367 break;
1368 }
1369 (*env)->DeleteLocalRef(env, fcFont);
1370 }
1371 }
1372 if (includeFallbacks) {
1373 (*env)->DeleteLocalRef(env, fcFontArr);
1374 }
1375 (*env)->DeleteLocalRef(env, fcCompFontObj);
1376 (*FcFontSetDestroy)(fontset);
1377 (*FcPatternDestroy)(pattern);
1378 free(family);
1379 free(styleStr);
1380 free(fullname);
1381 free(file);
1382 }
1383
1384 /* release resources and close the ".so" */
1385
1386 if (locale) {
1387 (*env)->ReleaseStringUTFChars (env, localeStr, (const char*)locale);
1388 }
1389 closeFontConfig(libfontconfig, JNI_TRUE);
1390 }
|
1 /*
2 * Copyright (c) 1998, 2019, 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
870 FcPatternDestroyFuncType FcPatternDestroy;
871
872 FcPattern *pattern, *matchPattern;
873 FcResult result;
874 FcBool antialias = FcFalse;
875 int rgba = 0;
876 const char *locale=NULL, *fcName=NULL;
877 void* libfontconfig;
878
879 if (fcNameStr == NULL || localeStr == NULL) {
880 return -1;
881 }
882
883 fcName = (*env)->GetStringUTFChars(env, fcNameStr, 0);
884 if (fcName == NULL) {
885 return -1;
886 }
887 locale = (*env)->GetStringUTFChars(env, localeStr, 0);
888
889 if ((libfontconfig = openFontConfig()) == NULL) {
890 (*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
891 if (locale) {
892 (*env)->ReleaseStringUTFChars(env, localeStr,(const char*)locale);
893 }
894 return -1;
895 }
896
897 FcNameParse = (FcNameParseFuncType)dlsym(libfontconfig, "FcNameParse");
898 FcPatternAddString =
899 (FcPatternAddStringFuncType)dlsym(libfontconfig, "FcPatternAddString");
900 FcConfigSubstitute =
901 (FcConfigSubstituteFuncType)dlsym(libfontconfig, "FcConfigSubstitute");
902 FcDefaultSubstitute = (FcDefaultSubstituteFuncType)
903 dlsym(libfontconfig, "FcDefaultSubstitute");
904 FcFontMatch = (FcFontMatchFuncType)dlsym(libfontconfig, "FcFontMatch");
905 FcPatternGetBool = (FcPatternGetBoolFuncType)
906 dlsym(libfontconfig, "FcPatternGetBool");
907 FcPatternGetInteger = (FcPatternGetIntegerFuncType)
908 dlsym(libfontconfig, "FcPatternGetInteger");
909 FcPatternDestroy =
910 (FcPatternDestroyFuncType)dlsym(libfontconfig, "FcPatternDestroy");
911
912 if (FcNameParse == NULL ||
913 FcPatternAddString == NULL ||
914 FcConfigSubstitute == NULL ||
915 FcDefaultSubstitute == NULL ||
916 FcFontMatch == NULL ||
917 FcPatternGetBool == NULL ||
918 FcPatternGetInteger == NULL ||
919 FcPatternDestroy == NULL) { /* problem with the library: return. */
920
921 (*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
922 if (locale) {
923 (*env)->ReleaseStringUTFChars(env, localeStr,(const char*)locale);
924 }
925 closeFontConfig(libfontconfig, JNI_FALSE);
926 return -1;
927 }
928
929
930 pattern = (*FcNameParse)((FcChar8 *)fcName);
931 if (locale != NULL) {
932 (*FcPatternAddString)(pattern, FC_LANG, (unsigned char*)locale);
933 }
934 (*FcConfigSubstitute)(NULL, pattern, FcMatchPattern);
935 (*FcDefaultSubstitute)(pattern);
936 matchPattern = (*FcFontMatch)(NULL, pattern, &result);
937 /* Perhaps should call FcFontRenderPrepare() here as some pattern
938 * elements might change as a result of that call, but I'm not seeing
939 * any difference in testing.
940 */
941 if (matchPattern) {
942 (*FcPatternGetBool)(matchPattern, FC_ANTIALIAS, 0, &antialias);
943 (*FcPatternGetInteger)(matchPattern, FC_RGBA, 0, &rgba);
944 (*FcPatternDestroy)(matchPattern);
945 }
946 (*FcPatternDestroy)(pattern);
947
948 (*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
949 if (locale) {
950 (*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
951 }
952 closeFontConfig(libfontconfig, JNI_TRUE);
953
954 if (antialias == FcFalse) {
955 return TEXT_AA_OFF;
956 } else if (rgba <= FC_RGBA_UNKNOWN || rgba >= FC_RGBA_NONE) {
957 return TEXT_AA_ON;
958 } else {
959 switch (rgba) {
960 case FC_RGBA_RGB : return TEXT_AA_LCD_HRGB;
961 case FC_RGBA_BGR : return TEXT_AA_LCD_HBGR;
962 case FC_RGBA_VRGB : return TEXT_AA_LCD_VRGB;
963 case FC_RGBA_VBGR : return TEXT_AA_LCD_VBGR;
964 default : return TEXT_AA_LCD_HRGB; // should not get here.
965 }
966 }
967 }
968
969 JNIEXPORT jint JNICALL
970 Java_sun_font_FontConfigManager_getFontConfigVersion
1162 int fn, j, fontCount, nfonts;
1163 unsigned int minGlyphs;
1164 FcChar8 **family, **styleStr, **fullname, **file;
1165 jarray fcFontArr = NULL;
1166 FcCharSet *unionCharset = NULL;
1167
1168 fcCompFontObj = (*env)->GetObjectArrayElement(env, fcCompFontArray, i);
1169 fcNameStr =
1170 (jstring)((*env)->GetObjectField(env, fcCompFontObj, fcNameID));
1171 fcName = (*env)->GetStringUTFChars(env, fcNameStr, 0);
1172 if (fcName == NULL) {
1173 (*env)->DeleteLocalRef(env, fcCompFontObj);
1174 (*env)->DeleteLocalRef(env, fcNameStr);
1175 continue;
1176 }
1177 pattern = (*FcNameParse)((FcChar8 *)fcName);
1178 (*env)->ReleaseStringUTFChars(env, fcNameStr, (const char*)fcName);
1179 (*env)->DeleteLocalRef(env, fcNameStr);
1180 if (pattern == NULL) {
1181 closeFontConfig(libfontconfig, JNI_FALSE);
1182 if (locale) {
1183 (*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
1184 }
1185 return;
1186 }
1187
1188 /* locale may not usually be necessary as fontconfig appears to apply
1189 * this anyway based on the user's environment. However we want
1190 * to use the value of the JDK startup locale so this should take
1191 * care of it.
1192 */
1193 if (locale != NULL) {
1194 (*FcPatternAddString)(pattern, FC_LANG, (unsigned char*)locale);
1195 }
1196 (*FcConfigSubstitute)(NULL, pattern, FcMatchPattern);
1197 (*FcDefaultSubstitute)(pattern);
1198 fontset = (*FcFontSort)(NULL, pattern, FcTrue, NULL, &result);
1199 if (fontset == NULL) {
1200 (*FcPatternDestroy)(pattern);
1201 closeFontConfig(libfontconfig, JNI_FALSE);
1202 if (locale) {
1203 (*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
1204 }
1205 return;
1206 }
1207
1208 /* fontconfig returned us "nfonts". If we are just getting the
1209 * first font, we set nfont to zero. Otherwise we use "nfonts".
1210 * Next create separate C arrrays of length nfonts for family file etc.
1211 * Inspect the returned fonts and the ones we like (adds enough glyphs)
1212 * are added to the arrays and we increment 'fontCount'.
1213 */
1214 nfonts = fontset->nfont;
1215 family = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
1216 styleStr = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
1217 fullname = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
1218 file = (FcChar8**)calloc(nfonts, sizeof(FcChar8*));
1219 if (family == NULL || styleStr == NULL ||
1220 fullname == NULL || file == NULL) {
1221 if (family != NULL) {
1222 free(family);
1223 }
1224 if (styleStr != NULL) {
1225 free(styleStr);
1226 }
1227 if (fullname != NULL) {
1228 free(fullname);
1229 }
1230 if (file != NULL) {
1231 free(file);
1232 }
1233 (*FcPatternDestroy)(pattern);
1234 (*FcFontSetDestroy)(fontset);
1235 closeFontConfig(libfontconfig, JNI_FALSE);
1236 if (locale) {
1237 (*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
1238 }
1239 return;
1240 }
1241 fontCount = 0;
1242 minGlyphs = 20;
1243 if (debugMinGlyphsStr != NULL) {
1244 int val = minGlyphs;
1245 sscanf(debugMinGlyphsStr, "%5d", &val);
1246 if (val >= 0 && val <= 65536) {
1247 minGlyphs = val;
1248 }
1249 }
1250
1251 for (j=0; j<nfonts; j++) {
1252 FcPattern *fontPattern = fontset->fonts[j];
1253 FcChar8 *fontformat;
1254 FcCharSet *charset = NULL;
1255
1256 fontformat = NULL;
1257 (*FcPatternGetString)(fontPattern, FC_FONTFORMAT, 0, &fontformat);
1258 /* We only want TrueType fonts but some Linuxes still depend
1261 */
1262 if (fontformat != NULL
1263 && (strcmp((char*)fontformat, "TrueType") != 0)
1264 #if defined(__linux__) || defined(_AIX)
1265 && (strcmp((char*)fontformat, "Type 1") != 0)
1266 && (strcmp((char*)fontformat, "CFF") != 0)
1267 #endif
1268 ) {
1269 continue;
1270 }
1271 result = (*FcPatternGetCharSet)(fontPattern,
1272 FC_CHARSET, 0, &charset);
1273 if (result != FcResultMatch) {
1274 free(family);
1275 free(fullname);
1276 free(styleStr);
1277 free(file);
1278 (*FcPatternDestroy)(pattern);
1279 (*FcFontSetDestroy)(fontset);
1280 closeFontConfig(libfontconfig, JNI_FALSE);
1281 if (locale) {
1282 (*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
1283 }
1284 return;
1285 }
1286
1287 /* We don't want 20 or 30 fonts, so once we hit 10 fonts,
1288 * then require that they really be adding value. Too many
1289 * adversely affects load time for minimal value-add.
1290 * This is still likely far more than we've had in the past.
1291 */
1292 if (j==10) {
1293 minGlyphs = 50;
1294 }
1295 if (unionCharset == NULL) {
1296 unionCharset = charset;
1297 } else {
1298 if ((*FcCharSetSubtractCount)(charset, unionCharset)
1299 > minGlyphs) {
1300 unionCharset = (* FcCharSetUnion)(unionCharset, charset);
1301 } else {
1302 continue;
1303 }
1318
1319 /* Once we get here 'fontCount' is the number of returned fonts
1320 * we actually want to use, so we create 'fcFontArr' of that length.
1321 * The non-null entries of "family[]" etc are those fonts.
1322 * Then loop again over all nfonts adding just those non-null ones
1323 * to 'fcFontArr'. If its null (we didn't want the font)
1324 * then we don't enter the main body.
1325 * So we should never get more than 'fontCount' entries.
1326 */
1327 if (includeFallbacks) {
1328 fcFontArr =
1329 (*env)->NewObjectArray(env, fontCount, fcFontClass, NULL);
1330 if (IS_NULL(fcFontArr)) {
1331 free(family);
1332 free(fullname);
1333 free(styleStr);
1334 free(file);
1335 (*FcPatternDestroy)(pattern);
1336 (*FcFontSetDestroy)(fontset);
1337 closeFontConfig(libfontconfig, JNI_FALSE);
1338 if (locale) {
1339 (*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
1340 }
1341 return;
1342 }
1343 (*env)->SetObjectField(env,fcCompFontObj, fcAllFontsID, fcFontArr);
1344 }
1345 fn=0;
1346
1347 for (j=0;j<nfonts;j++) {
1348 if (family[j] != NULL) {
1349 jobject fcFont =
1350 (*env)->NewObject(env, fcFontClass, fcFontCons);
1351 if (IS_NULL(fcFont)) break;
1352 jstr = (*env)->NewStringUTF(env, (const char*)family[j]);
1353 if (IS_NULL(jstr)) break;
1354 (*env)->SetObjectField(env, fcFont, familyNameID, jstr);
1355 (*env)->DeleteLocalRef(env, jstr);
1356 if (file[j] != NULL) {
1357 jstr = (*env)->NewStringUTF(env, (const char*)file[j]);
1358 if (IS_NULL(jstr)) break;
1359 (*env)->SetObjectField(env, fcFont, fontFileID, jstr);
1360 (*env)->DeleteLocalRef(env, jstr);
1382 break;
1383 }
1384 (*env)->DeleteLocalRef(env, fcFont);
1385 }
1386 }
1387 if (includeFallbacks) {
1388 (*env)->DeleteLocalRef(env, fcFontArr);
1389 }
1390 (*env)->DeleteLocalRef(env, fcCompFontObj);
1391 (*FcFontSetDestroy)(fontset);
1392 (*FcPatternDestroy)(pattern);
1393 free(family);
1394 free(styleStr);
1395 free(fullname);
1396 free(file);
1397 }
1398
1399 /* release resources and close the ".so" */
1400
1401 if (locale) {
1402 (*env)->ReleaseStringUTFChars(env, localeStr, (const char*)locale);
1403 }
1404 closeFontConfig(libfontconfig, JNI_TRUE);
1405 }
|