< prev index next >

src/java.desktop/unix/native/common/awt/fontpath.c

Print this page
rev 56251 : 8230900: missing ReleaseStringUTFChars in java.desktop native code
   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


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);


   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


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);


< prev index next >