< prev index next >

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

Print this page
rev 59383 : [mq]: final
   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
  23  * questions.
  24  */
  25 
  26 #if defined(__linux__)
  27 #include <string.h>
  28 #endif /* __linux__ */
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <strings.h>
  32 #include <sys/types.h>
  33 #include <sys/stat.h>
  34 #include <sys/mman.h>
  35 #include <fcntl.h>
  36 #include <unistd.h>
  37 #ifdef __solaris__
  38 #include <sys/systeminfo.h>
  39 #endif
  40 
  41 #include <jni.h>
  42 #include <jni_util.h>
  43 #include <jvm_md.h>
  44 #include <sizecalc.h>
  45 #ifndef HEADLESS
  46 #include <X11/Xlib.h>
  47 #include <awt.h>
  48 #else
  49 /* locks ought to be included from awt.h */
  50 #define AWT_LOCK()
  51 #define AWT_UNLOCK()
  52 #endif /* !HEADLESS */
  53 
  54 #if defined(__linux__) && !defined(MAP_FAILED)
  55 #define MAP_FAILED ((caddr_t)-1)
  56 #endif
  57 
  58 #ifndef HEADLESS
  59 extern Display *awt_display;
  60 #endif /* !HEADLESS */
  61 
  62 #define FONTCONFIG_DLL_VERSIONED VERSIONED_JNI_LIB_NAME("fontconfig", "1")
  63 #define FONTCONFIG_DLL JNI_LIB_NAME("fontconfig")
  64 
  65 #define MAXFDIRS 512    /* Max number of directories that contain fonts */
  66 
  67 #if defined(__solaris__)
  68 /*
  69  * This can be set in the makefile to "/usr/X11" if so desired.
  70  */
  71 #ifndef OPENWINHOMELIB
  72 #define OPENWINHOMELIB "/usr/openwin/lib/"
  73 #endif
  74 
  75 /* This is all known Solaris X11 directories on Solaris 8, 9 and 10.
  76  * It is ordered to give precedence to TrueType directories.
  77  * It is needed if fontconfig is not installed or configured properly.
  78  */
  79 static char *fullSolarisFontPath[] = {
  80     OPENWINHOMELIB "X11/fonts/TrueType",
  81     OPENWINHOMELIB "locale/euro_fonts/X11/fonts/TrueType",
  82     OPENWINHOMELIB "locale/iso_8859_2/X11/fonts/TrueType",
  83     OPENWINHOMELIB "locale/iso_8859_5/X11/fonts/TrueType",
  84     OPENWINHOMELIB "locale/iso_8859_7/X11/fonts/TrueType",
  85     OPENWINHOMELIB "locale/iso_8859_8/X11/fonts/TrueType",
  86     OPENWINHOMELIB "locale/iso_8859_9/X11/fonts/TrueType",
  87     OPENWINHOMELIB "locale/iso_8859_13/X11/fonts/TrueType",
  88     OPENWINHOMELIB "locale/iso_8859_15/X11/fonts/TrueType",
  89     OPENWINHOMELIB "locale/ar/X11/fonts/TrueType",
  90     OPENWINHOMELIB "locale/hi_IN.UTF-8/X11/fonts/TrueType",
  91     OPENWINHOMELIB "locale/ja/X11/fonts/TT",
  92     OPENWINHOMELIB "locale/ko/X11/fonts/TrueType",
  93     OPENWINHOMELIB "locale/ko.UTF-8/X11/fonts/TrueType",
  94     OPENWINHOMELIB "locale/KOI8-R/X11/fonts/TrueType",
  95     OPENWINHOMELIB "locale/ru.ansi-1251/X11/fonts/TrueType",
  96     OPENWINHOMELIB "locale/th_TH/X11/fonts/TrueType",
  97     OPENWINHOMELIB "locale/zh_TW/X11/fonts/TrueType",
  98     OPENWINHOMELIB "locale/zh_TW.BIG5/X11/fonts/TT",
  99     OPENWINHOMELIB "locale/zh_HK.BIG5HK/X11/fonts/TT",
 100     OPENWINHOMELIB "locale/zh_CN.GB18030/X11/fonts/TrueType",
 101     OPENWINHOMELIB "locale/zh/X11/fonts/TrueType",
 102     OPENWINHOMELIB "locale/zh.GBK/X11/fonts/TrueType",
 103     OPENWINHOMELIB "X11/fonts/Type1",
 104     OPENWINHOMELIB "X11/fonts/Type1/sun",
 105     OPENWINHOMELIB "X11/fonts/Type1/sun/outline",
 106     OPENWINHOMELIB "locale/iso_8859_2/X11/fonts/Type1",
 107     OPENWINHOMELIB "locale/iso_8859_4/X11/fonts/Type1",
 108     OPENWINHOMELIB "locale/iso_8859_5/X11/fonts/Type1",
 109     OPENWINHOMELIB "locale/iso_8859_7/X11/fonts/Type1",
 110     OPENWINHOMELIB "locale/iso_8859_8/X11/fonts/Type1",
 111     OPENWINHOMELIB "locale/iso_8859_9/X11/fonts/Type1",
 112     OPENWINHOMELIB "locale/iso_8859_13/X11/fonts/Type1",
 113     OPENWINHOMELIB "locale/ar/X11/fonts/Type1",
 114     NULL, /* terminates the list */
 115 };
 116 
 117 #elif defined( __linux__)
 118 /* All the known interesting locations we have discovered on
 119  * various flavors of Linux
 120  */
 121 static char *fullLinuxFontPath[] = {
 122     "/usr/X11R6/lib/X11/fonts/TrueType",  /* RH 7.1+ */
 123     "/usr/X11R6/lib/X11/fonts/truetype",  /* SuSE */
 124     "/usr/X11R6/lib/X11/fonts/tt",
 125     "/usr/X11R6/lib/X11/fonts/TTF",
 126     "/usr/X11R6/lib/X11/fonts/OTF",       /* RH 9.0 (but empty!) */
 127     "/usr/share/fonts/ja/TrueType",       /* RH 7.2+ */
 128     "/usr/share/fonts/truetype",
 129     "/usr/share/fonts/ko/TrueType",       /* RH 9.0 */
 130     "/usr/share/fonts/zh_CN/TrueType",    /* RH 9.0 */
 131     "/usr/share/fonts/zh_TW/TrueType",    /* RH 9.0 */
 132     "/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType", /* Debian */
 133     "/usr/X11R6/lib/X11/fonts/Type1",
 134     "/usr/share/fonts/default/Type1",     /* RH 9.0 */
 135     NULL, /* terminates the list */
 136 };
 137 #elif defined(_AIX)


 347     pos = 0;
 348     for (i=0; i < nPaths; i++) {
 349         if (x11Path[i][0] != '/') {
 350             continue;
 351         }
 352         if (strstr(x11Path[i], "/75dpi") != NULL) {
 353             continue;
 354         }
 355         if (strstr(x11Path[i], "/100dpi") != NULL) {
 356             continue;
 357         }
 358         if (strstr(x11Path[i], "/misc") != NULL) {
 359             continue;
 360         }
 361         if (strstr(x11Path[i], "/Speedo") != NULL) {
 362             continue;
 363         }
 364         if (strstr(x11Path[i], ".gnome") != NULL) {
 365             continue;
 366         }
 367 #ifdef __solaris__
 368         if (strstr(x11Path[i], "/F3/") != NULL) {
 369             continue;
 370         }
 371         if (strstr(x11Path[i], "bitmap") != NULL) {
 372             continue;
 373         }
 374 #endif
 375         fontdirs[pos] = strdup(x11Path[i]);
 376         slen = strlen(fontdirs[pos]);
 377         if (slen > 0 && fontdirs[pos][slen-1] == '/') {
 378             fontdirs[pos][slen-1] = '\0'; /* null out trailing "/"  */
 379         }
 380         pos++;
 381     }
 382 
 383     XFreeFontPath(x11Path);
 384     if (pos == 0) {
 385         free(fontdirs);
 386         fontdirs = NULL;
 387     }
 388     return fontdirs;
 389 }
 390 
 391 
 392 #endif /* !HEADLESS */
 393 
 394 #if defined(__linux__)


 504  * need to be added ito the host's font configuration database, typically
 505  * /etc/fonts/local.conf, and to ensure that directory contains a fonts.dir
 506  * NB: Fontconfig also depends heavily for performance on the host O/S
 507  * maintaining up to date caches.
 508  * This is consistent with the requirements of the desktop environments
 509  * on these OSes.
 510  * This also frees us from X11 APIs as JRE is required to function in
 511  * a "headless" mode where there is no Xserver.
 512  */
 513 static char *getPlatformFontPathChars(JNIEnv *env, jboolean noType1, jboolean isX11) {
 514 
 515     char **fcdirs = NULL, **x11dirs = NULL, **knowndirs = NULL, *path = NULL;
 516 
 517     /* As of 1.5 we try to use fontconfig on both Solaris and Linux.
 518      * If its not available NULL is returned.
 519      */
 520     fcdirs = getFontConfigLocations();
 521 
 522 #if defined(__linux__)
 523     knowndirs = fullLinuxFontPath;
 524 #elif defined(__solaris__)
 525     knowndirs = fullSolarisFontPath;
 526 #elif defined(_AIX)
 527     knowndirs = fullAixFontPath;
 528 #endif
 529     /* REMIND: this code requires to be executed when the GraphicsEnvironment
 530      * is already initialised. That is always true, but if it were not so,
 531      * this code could throw an exception and the fontpath would fail to
 532      * be initialised.
 533      */
 534 #ifndef HEADLESS
 535     if (isX11) { // The following only works in an x11 environment.
 536 #if defined(__linux__)
 537     /* There's no headless build on linux ... */
 538     if (!AWTIsHeadless()) { /* .. so need to call a function to check */
 539 #endif
 540       /* Using the X11 font path to locate font files is now a fallback
 541        * useful only if fontconfig failed, or is incomplete. So we could
 542        * remove this code completely and the consequences should be rare
 543        * and non-fatal. If this happens, then the calling Java code can
 544        * be modified to no longer require that the AWT lock (the X11GE)
 545        * be initialised prior to calling this code.


 575     jstring ret;
 576     static char *ptr = NULL; /* retain result across calls */
 577 
 578     if (ptr == NULL) {
 579         ptr = getPlatformFontPathChars(env, noType1, isX11);
 580     }
 581     ret = (*env)->NewStringUTF(env, ptr);
 582     return ret;
 583 }
 584 
 585 #include <dlfcn.h>
 586 
 587 #include <fontconfig/fontconfig.h>
 588 
 589 
 590 static void* openFontConfig() {
 591 
 592     char *homeEnv;
 593     static char *homeEnvStr = "HOME="; /* must be static */
 594     void* libfontconfig = NULL;
 595 #ifdef __solaris__
 596 #define SYSINFOBUFSZ 8
 597     char sysinfobuf[SYSINFOBUFSZ];
 598 #endif
 599 
 600     /* Private workaround to not use fontconfig library.
 601      * May be useful during testing/debugging
 602      */
 603     char *useFC = getenv("USE_J2D_FONTCONFIG");
 604     if (useFC != NULL && !strcmp(useFC, "no")) {
 605         return NULL;
 606     }
 607 
 608 #ifdef __solaris__
 609     /* fontconfig is likely not properly configured on S8/S9 - skip it,
 610      * although allow user to override this behaviour with an env. variable
 611      * ie if USE_J2D_FONTCONFIG=yes then we skip this test.
 612      * NB "4" is the length of a string which matches our patterns.
 613      */
 614     if (useFC == NULL || strcmp(useFC, "yes")) {
 615         if (sysinfo(SI_RELEASE, sysinfobuf, SYSINFOBUFSZ) == 4) {
 616             if ((!strcmp(sysinfobuf, "5.8") || !strcmp(sysinfobuf, "5.9"))) {
 617                 return NULL;
 618             }
 619         }
 620     }
 621 #endif
 622 
 623 #if defined(_AIX)
 624     /* On AIX, fontconfig is not a standard package supported by IBM.
 625      * instead it has to be installed from the "AIX Toolbox for Linux Applications"
 626      * site http://www-03.ibm.com/systems/power/software/aix/linux/toolbox/alpha.html
 627      * and will be installed under /opt/freeware/lib/libfontconfig.a.
 628      * Notice that the archive contains the real 32- and 64-bit shared libraries.
 629      * We first try to load 'libfontconfig.so' from the default library path in the
 630      * case the user has installed a private version of the library and if that
 631      * doesn't succeed, we try the version from /opt/freeware/lib/libfontconfig.a
 632      */
 633     libfontconfig = dlopen("libfontconfig.so", RTLD_LOCAL|RTLD_LAZY);
 634     if (libfontconfig == NULL) {
 635         libfontconfig = dlopen("/opt/freeware/lib/libfontconfig.a(libfontconfig.so.1)", RTLD_MEMBER|RTLD_LOCAL|RTLD_LAZY);
 636         if (libfontconfig == NULL) {
 637             return NULL;
 638         }
 639     }
 640 #else
 641     /* 64 bit sparc should pick up the right version from the lib path.


   1 /*
   2  * Copyright (c) 1998, 2020, 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
  23  * questions.
  24  */
  25 
  26 #if defined(__linux__)
  27 #include <string.h>
  28 #endif /* __linux__ */
  29 #include <stdio.h>
  30 #include <stdlib.h>
  31 #include <strings.h>
  32 #include <sys/types.h>
  33 #include <sys/stat.h>
  34 #include <sys/mman.h>
  35 #include <fcntl.h>
  36 #include <unistd.h>



  37 
  38 #include <jni.h>
  39 #include <jni_util.h>
  40 #include <jvm_md.h>
  41 #include <sizecalc.h>
  42 #ifndef HEADLESS
  43 #include <X11/Xlib.h>
  44 #include <awt.h>
  45 #else
  46 /* locks ought to be included from awt.h */
  47 #define AWT_LOCK()
  48 #define AWT_UNLOCK()
  49 #endif /* !HEADLESS */
  50 
  51 #if defined(__linux__) && !defined(MAP_FAILED)
  52 #define MAP_FAILED ((caddr_t)-1)
  53 #endif
  54 
  55 #ifndef HEADLESS
  56 extern Display *awt_display;
  57 #endif /* !HEADLESS */
  58 
  59 #define FONTCONFIG_DLL_VERSIONED VERSIONED_JNI_LIB_NAME("fontconfig", "1")
  60 #define FONTCONFIG_DLL JNI_LIB_NAME("fontconfig")
  61 
  62 #define MAXFDIRS 512    /* Max number of directories that contain fonts */
  63 
  64 #if defined( __linux__)


















































  65 /* All the known interesting locations we have discovered on
  66  * various flavors of Linux
  67  */
  68 static char *fullLinuxFontPath[] = {
  69     "/usr/X11R6/lib/X11/fonts/TrueType",  /* RH 7.1+ */
  70     "/usr/X11R6/lib/X11/fonts/truetype",  /* SuSE */
  71     "/usr/X11R6/lib/X11/fonts/tt",
  72     "/usr/X11R6/lib/X11/fonts/TTF",
  73     "/usr/X11R6/lib/X11/fonts/OTF",       /* RH 9.0 (but empty!) */
  74     "/usr/share/fonts/ja/TrueType",       /* RH 7.2+ */
  75     "/usr/share/fonts/truetype",
  76     "/usr/share/fonts/ko/TrueType",       /* RH 9.0 */
  77     "/usr/share/fonts/zh_CN/TrueType",    /* RH 9.0 */
  78     "/usr/share/fonts/zh_TW/TrueType",    /* RH 9.0 */
  79     "/var/lib/defoma/x-ttcidfont-conf.d/dirs/TrueType", /* Debian */
  80     "/usr/X11R6/lib/X11/fonts/Type1",
  81     "/usr/share/fonts/default/Type1",     /* RH 9.0 */
  82     NULL, /* terminates the list */
  83 };
  84 #elif defined(_AIX)


 294     pos = 0;
 295     for (i=0; i < nPaths; i++) {
 296         if (x11Path[i][0] != '/') {
 297             continue;
 298         }
 299         if (strstr(x11Path[i], "/75dpi") != NULL) {
 300             continue;
 301         }
 302         if (strstr(x11Path[i], "/100dpi") != NULL) {
 303             continue;
 304         }
 305         if (strstr(x11Path[i], "/misc") != NULL) {
 306             continue;
 307         }
 308         if (strstr(x11Path[i], "/Speedo") != NULL) {
 309             continue;
 310         }
 311         if (strstr(x11Path[i], ".gnome") != NULL) {
 312             continue;
 313         }








 314         fontdirs[pos] = strdup(x11Path[i]);
 315         slen = strlen(fontdirs[pos]);
 316         if (slen > 0 && fontdirs[pos][slen-1] == '/') {
 317             fontdirs[pos][slen-1] = '\0'; /* null out trailing "/"  */
 318         }
 319         pos++;
 320     }
 321 
 322     XFreeFontPath(x11Path);
 323     if (pos == 0) {
 324         free(fontdirs);
 325         fontdirs = NULL;
 326     }
 327     return fontdirs;
 328 }
 329 
 330 
 331 #endif /* !HEADLESS */
 332 
 333 #if defined(__linux__)


 443  * need to be added ito the host's font configuration database, typically
 444  * /etc/fonts/local.conf, and to ensure that directory contains a fonts.dir
 445  * NB: Fontconfig also depends heavily for performance on the host O/S
 446  * maintaining up to date caches.
 447  * This is consistent with the requirements of the desktop environments
 448  * on these OSes.
 449  * This also frees us from X11 APIs as JRE is required to function in
 450  * a "headless" mode where there is no Xserver.
 451  */
 452 static char *getPlatformFontPathChars(JNIEnv *env, jboolean noType1, jboolean isX11) {
 453 
 454     char **fcdirs = NULL, **x11dirs = NULL, **knowndirs = NULL, *path = NULL;
 455 
 456     /* As of 1.5 we try to use fontconfig on both Solaris and Linux.
 457      * If its not available NULL is returned.
 458      */
 459     fcdirs = getFontConfigLocations();
 460 
 461 #if defined(__linux__)
 462     knowndirs = fullLinuxFontPath;


 463 #elif defined(_AIX)
 464     knowndirs = fullAixFontPath;
 465 #endif
 466     /* REMIND: this code requires to be executed when the GraphicsEnvironment
 467      * is already initialised. That is always true, but if it were not so,
 468      * this code could throw an exception and the fontpath would fail to
 469      * be initialised.
 470      */
 471 #ifndef HEADLESS
 472     if (isX11) { // The following only works in an x11 environment.
 473 #if defined(__linux__)
 474     /* There's no headless build on linux ... */
 475     if (!AWTIsHeadless()) { /* .. so need to call a function to check */
 476 #endif
 477       /* Using the X11 font path to locate font files is now a fallback
 478        * useful only if fontconfig failed, or is incomplete. So we could
 479        * remove this code completely and the consequences should be rare
 480        * and non-fatal. If this happens, then the calling Java code can
 481        * be modified to no longer require that the AWT lock (the X11GE)
 482        * be initialised prior to calling this code.


 512     jstring ret;
 513     static char *ptr = NULL; /* retain result across calls */
 514 
 515     if (ptr == NULL) {
 516         ptr = getPlatformFontPathChars(env, noType1, isX11);
 517     }
 518     ret = (*env)->NewStringUTF(env, ptr);
 519     return ret;
 520 }
 521 
 522 #include <dlfcn.h>
 523 
 524 #include <fontconfig/fontconfig.h>
 525 
 526 
 527 static void* openFontConfig() {
 528 
 529     char *homeEnv;
 530     static char *homeEnvStr = "HOME="; /* must be static */
 531     void* libfontconfig = NULL;




 532 
 533     /* Private workaround to not use fontconfig library.
 534      * May be useful during testing/debugging
 535      */
 536     char *useFC = getenv("USE_J2D_FONTCONFIG");
 537     if (useFC != NULL && !strcmp(useFC, "no")) {
 538         return NULL;
 539     }















 540 
 541 #if defined(_AIX)
 542     /* On AIX, fontconfig is not a standard package supported by IBM.
 543      * instead it has to be installed from the "AIX Toolbox for Linux Applications"
 544      * site http://www-03.ibm.com/systems/power/software/aix/linux/toolbox/alpha.html
 545      * and will be installed under /opt/freeware/lib/libfontconfig.a.
 546      * Notice that the archive contains the real 32- and 64-bit shared libraries.
 547      * We first try to load 'libfontconfig.so' from the default library path in the
 548      * case the user has installed a private version of the library and if that
 549      * doesn't succeed, we try the version from /opt/freeware/lib/libfontconfig.a
 550      */
 551     libfontconfig = dlopen("libfontconfig.so", RTLD_LOCAL|RTLD_LAZY);
 552     if (libfontconfig == NULL) {
 553         libfontconfig = dlopen("/opt/freeware/lib/libfontconfig.a(libfontconfig.so.1)", RTLD_MEMBER|RTLD_LOCAL|RTLD_LAZY);
 554         if (libfontconfig == NULL) {
 555             return NULL;
 556         }
 557     }
 558 #else
 559     /* 64 bit sparc should pick up the right version from the lib path.


< prev index next >