fontpath.c revision 760
0N/A * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. Sun designates this 0N/A * particular file as subject to the "Classpath" exception as provided 0N/A * by Sun in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 0N/A * CA 95054 USA or visit www.sun.com if you need additional information or 0N/A * have any questions. 0N/A#
endif /* __linux__ */ 0N/A/* locks ought to be included from awt.h */ 0N/A#
endif /* !HEADLESS */ 0N/A#
endif /* !HEADLESS */ 0N/A#
define MAXFDIRS 512 /* Max number of directories that contain fonts */ 0N/A * This can be set in the makefile to "/usr/X11" if so desired. 0N/A/* This is all known Solaris X11 directories on Solaris 8, 9 and 10. 0N/A * It is ordered to give precedence to TrueType directories. 0N/A * It is needed if fontconfig is not installed or configured properly. 0N/A/* All the known interesting locations we have discovered on 0N/A * various flavors of Linux 0N/A * Returns True if display is local, False of it's remote. 0N/A return;
/* if it fails we cannot do much */ 0N/A /* there is a slash at the end of every solaris X11 font path name */ 0N/A /* if no changes are required do not bother to do a setfontpath */ 0N/A /* if it fails free things and get out */ 0N/A /* now add the other font paths */ 0N/A /* printf ( "Appending %s\n", fDirP->name[index] ); */ 0N/A /* printf ( "The path to be appended is %s\n", onePath ); */ 0N/A /* printf ( "The dir count = %d\n", totalDirCount ); */ 0N/A#
endif /* !HEADLESS */ 0N/A /* This isn't ever going to be perfect: the font path may contain 0N/A * much we aren't interested in, but the cost should be moderate 0N/A * Exclude all directories that contain the strings "Speedo","/F3/", 0N/A * "75dpi", "100dpi", "misc" or "bitmap", or don't begin with a "/", 0N/A * the last of which should exclude font servers. 0N/A * Also exclude the user specific ".gnome*" directories which 0N/A * aren't going to contain the system fonts we need. 0N/A * Hopefully we are left only with Type1 and TrueType directories. 0N/A * It doesn't matter much if there are extraneous directories, it'll just 0N/A * cost us a little wasted effort upstream. 0N/A#
endif /* !HEADLESS */ 0N/A/* This eliminates duplicates, at a non-linear but acceptable cost 0N/A * since the lists are expected to be reasonably short, and then 0N/A * deletes references to non-existent directories, and returns 0N/A * a single path consisting of unique font directories. 0N/A /* Now fontdirs contains unique dirs and numDirs records how many. 0N/A * What we don't know is if they all exist. On reflection I think 0N/A * this isn't an issue, so for now I will return all these locations, 0N/A * converted to one string */ 0N/A * The goal of this function is to find all "system" fonts which 0N/A * are needed by the JRE to display text in supported locales etc, and 0N/A * to support APIs which allow users to enumerate all system fonts and use 0N/A * them from their Java applications. 0N/A * The preferred mechanism is now using the new "fontconfig" library 0N/A * This exists on newer versions of Linux and Solaris (S10 and above) 0N/A * The library is dynamically located. The results are merged with 0N/A * a set of "known" locations and with the X11 font path, if running in 0N/A * a local X11 environment. 0N/A * The hardwired paths are built into the JDK binary so as new font locations 0N/A * are created on a host plaform for them to be located by the JRE they will 0N/A * need to be added ito the host's font configuration database, typically 0N/A * NB: Fontconfig also depends heavily for performance on the host O/S 0N/A * maintaining up to date caches. 0N/A * This is consistent with the requirements of the desktop environments 0N/A * This also frees us from X11 APIs as JRE is required to function in 0N/A * a "headless" mode where there is no Xserver. 0N/A /* As of 1.5 we try to use fontconfig on both Solaris and Linux. 0N/A * If its not available NULL is returned. 0N/A#
else /* IF SOLARIS */ 0N/A /* REMIND: this code requires to be executed when the GraphicsEnvironment 0N/A * is already initialised. That is always true, but if it were not so, 0N/A * this code could throw an exception and the fontpath would fail to 0N/A#
ifdef __linux__ /* There's no headless build on linux ... */ 0N/A#
endif /* !HEADLESS */ 0N/A static char *
ptr =
NULL;
/* retain result across calls */ 0N/A * In general setting the font path in a remote display situation is 0N/A * problematic. But for Solaris->Solaris the paths needed by the JRE should 0N/A * also be available to the server, although we have no way to check this 0N/A * So set the font path if we think its safe to do so: 0N/A * All Solaris X servers at least back to 2.6 and up to Solaris 10 0N/A * define the exact same vendor string. 0N/A * The version number for Solaris 2.6 is 3600, for 2.7 is 3610 and 0N/A * for Solaris 8 6410 0N/A * we want to set the font path only for 2.8 and onwards. Earlier releases 0N/A * are unlikely to have the right fonts and can't install "all locales" 0N/A * as needed to be sure. Also Solaris 8 is the earliest release supported 0N/A#
endif /* __solaris__ */ 0N/A/* Avoid re-doing work for every call to setNativeFontPath */ 0N/A#
endif /* !HEADLESS */ 0N/A /* printf ("Registering the font path here %s \n", theChars ); */ 0N/A/* This isn't yet used on unix, the implementation is added since shared 0N/A * code calls this method in preparation for future use. 0N/A/* Obtain all the fontname -> filename mappings. 0N/A * This is called once and the results returned to Java code which can 0N/A * use it for lookups to reduce or avoid the need to search font files. 0N/A /* Private workaround to not use fontconfig library. 0N/A /* fontconfig is likely not properly configured on S8/S9 - skip it, 0N/A * although allow user to override this behaviour with an env. variable 0N/A * ie if USE_J2D_FONTCONFIG=yes then we skip this test. 0N/A * NB "4" is the length of a string which matches our patterns. 0N/A /* 64 bit sparc should pick up the right version from the lib path. 0N/A * New features may be added to libfontconfig, this is expected to 0N/A * be compatible with old features, but we may need to start 0N/A * distinguishing the library version, to know whether to expect 0N/A * certain symbols - and functionality - to be available. 0N/A * Also add explicit search for .so.1 in case .so symlink doesn't exist. 0N/A /* Version 1.0 of libfontconfig crashes if HOME isn't defined in 0N/A * the environment. This should generally never happen, but we can't 0N/A * control it, and can't control the version of fontconfig, so iff 0N/A * its not defined we set it to an empty value which is sufficient 0N/A * to prevent a crash. I considered unsetting it before exit, but 0N/A * it doesn't appear to work on Solaris, so I will leave it set. 0N/A /* NB FcFini is not in (eg) the Solaris 10 version of fontconfig. Its not 0N/A * clear if this means we are really leaking resources in those cases 0N/A * but it seems we should call this function when its available. 0N/A * But since the Swing GTK code may be still accessing the lib, its probably 0N/A * safest for now to just let this "leak" rather than potentially 0N/A * concurrently free global data still in use by other code. 0N/A /* Make calls into the fontconfig library to build a search for 0N/A * outline fonts, and to get the set of full file paths from the matches. 0N/A * This set is returned from the call to FcFontList(..) 0N/A * We allocate an array of char* pointers sufficient to hold all 0N/A * the matches + 1 extra which ensures there will be a NULL after all 0N/A * We call FcStrDirname strip the file name from the path, and 0N/A * check if we have yet seen this directory. If not we add a pointer to 0N/A * it into our array of char*. Note that FcStrDirname returns newly 0N/A * allocated storage so we can use this in the return char** value. 0N/A * Finally we clean up, freeing allocated resources, and return the 0N/A * array of unique directories. 0N/A /* Free memory and close the ".so" */ 0N/A/* These are copied from sun.awt.SunHints. 0N/A * Consider initialising them as ints using JNI for more robustness. 0N/A /* Perhaps should call FcFontRenderPrepare() here as some pattern 0N/A * elements might change as a result of that call, but I'm not seeing 0N/A * any difference in testing. 426N/A "FcPatternGetCharSet");
426N/A "FcCharSetSubtractCount");
426N/A /* Optionally get the cache dir locations. This isn't 426N/A * available until v 2.4.x, but this is OK since on those later versions 426N/A * we can check the time stamps on the cache dirs to see if we 426N/A * are out of date. There are a couple of assumptions here. First 426N/A * that the time stamp on the directory changes when the contents are 426N/A * updated. Secondly that the locations don't change. The latter is 426N/A * most likely if a new version of fontconfig is installed, but we also 426N/A * invalidate the cache if we detect that. Arguably even that is "rare", 426N/A * and most likely is tied to an OS upgrade which gets a new file anyway. 426N/A "FcConfigGetCacheDirs");
0N/A /* locale may not usually be necessary as fontconfig appears to apply 0N/A * this anyway based on the user's environment. However we want 0N/A * to use the value of the JDK startup locale so this should take 426N/A /* fontconfig returned us "nfonts". If we are just getting the 426N/A * first font, we set nfont to zero. Otherwise we use "nfonts". 426N/A * Next create separate C arrrays of length nfonts for family file etc. 426N/A * Inspect the returned fonts and the ones we like (adds enough glyphs) 426N/A * are added to the arrays and we increment 'fontCount'. 426N/A /* We don't want 20 or 30 fonts, so once we hit 10 fonts, 426N/A * then require that they really be adding value. Too many 426N/A * adversely affects load time for minimal value-add. 426N/A * This is still likely far more than we've had in the past. 426N/A /* Once we get here 'fontCount' is the number of returned fonts 426N/A * we actually want to use, so we create 'fcFontArr' of that length. 426N/A * The non-null entries of "family[]" etc are those fonts. 426N/A * Then loop again over all nfonts adding just those non-null ones 426N/A * to 'fcFontArr'. If its null (we didn't want the font) 426N/A * then we don't enter the main body. 426N/A * So we should never get more than 'fontCount' entries. 0N/A /* release resources and close the ".so" */