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.
|