/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* The base implementation of the {@link FontManager} interface. It implements
* the platform independent, shared parts of OpenJDK's FontManager
* implementations. The platform specific parts are declared as abstract
* methods that have to be implemented by specific implementations.
*/
/* all conveniently have the same suffix length */
return false;
} else {
}
}
}
if (noType1Font) {
return false;
}
/* all conveniently have the same suffix length */
return false;
} else {
}
}
}
/* all conveniently have the same suffix length */
return false;
} else {
boolean isTT =
if (isTT) {
return true;
} else if (noType1Font) {
return false;
} else {
}
}
}
}
/* Pool of 20 font file channels chosen because some UTF-8 locale
* composite fonts can use up to 16 platform fonts (including the
* Lucida fall back). This should prevent channel thrashing when
* dealing with one of these fonts.
* The pool array stores the fonts, rather than directly referencing
*/
// MACOSX begin -- need to access these in subclass
// MACOSX end
/* Need to implement a simple linked list scheme for fast
* traversal and lookup.
* Also want to "fast path" dialog so there's minimal overhead.
*/
/* There are at exactly 20 composite fonts: 5 faces (but some are not
* usually different), in 4 styles. The array may be auto-expanded
* later if more are needed, eg for user-defined composites or locale
* variants.
*/
/* given a full name find the Font. Remind: there's duplication
* here in that this contains the content of compositeFonts +
* physicalFonts.
*/
// MACOSX begin -- need to access this in subclass
// MACOSX end
/* TrueType fonts have localised names. Support searching all
* of these before giving up on a name.
*/
static boolean longAddresses;
private boolean loaded1dot0Fonts = false;
boolean loadedAllFonts = false;
boolean loadedAllFontFiles = false;
/* fontPath is the location of all fonts on the system, excluding the
* JRE's own font directory but including any path specified using the
* sun.java2d.fontpath property. Together with that property, it is
* initialised by the getPlatformFontPath() method
* This call must be followed by a call to registerFontDirs(fontPath)
* once any extra debugging path has been appended.
*/
/* discoveredAllFonts is set to true when all fonts on the font path are
* discovered. This usually also implies opening, validating and
* registering, but an implementation may be optimized to avold this.
* So see also "loadedAllFontFiles"
*/
private boolean discoveredAllFonts = false;
/* No need to keep consing up new instances - reuse a singleton.
* The trade-off is that these objects don't get GC'd.
*/
public static boolean noType1Font;
/* Used to indicate required return type from toArray(..); */
/**
* Deprecated, unsupported hack - actually invokes a bug!
* Left in for a customer, don't remove.
*/
private boolean usePlatformFontMetrics = false;
/**
* Returns the global SunFontManager instance. This is similar to
* {@link FontManagerFactory#getInstance()} but it returns a
* SunFontManager instance instead. This is only used in internal classes
* where we can safely assume that a SunFontManager is to be used.
*
* @return the global SunFontManager instance
*/
return (SunFontManager) fm;
}
return ttFilter;
}
return t1Filter;
}
public boolean usingPerAppContextComposites() {
return _usingPerAppContextComposites;
}
private void initJREFontMap() {
/* Key is familyname+style value as an int.
* Value is filename containing the font.
* If no mapping exists, it means there is no font file for the style
* If the mapping exists but the file doesn't exist in the deferred
* list then it means its not installed.
* This looks like a lot of code and strings but if it saves even
* a single file being opened at JRE start-up there's a big payoff.
* Lucida Sans is probably the only important case as the others
* are rarely used. Consider removing the other mappings if there's
* no evidence they are useful in practice.
*/
if (isOpenJDK()) {
return;
}
/* Lucida Sans Family */
/* Lucida Sans full names (map Bold and DemiBold to same file) */
/* Lucida Sans Typewriter Family */
"LucidaTypewriterRegular.ttf");
/* Typewriter full names (map Bold and DemiBold to same file) */
"LucidaTypewriter.ttf");
"LucidaTypewriterBold.ttf");
"LucidaTypewriterBold.ttf");
"LucidaTypewriterBold.ttf");
/* Lucida Bright Family */
/* Lucida Bright full names (map Bold and DemiBold to same file) */
"LucidaBrightDemiItalic.ttf");
"LucidaBrightDemiItalic.ttf");
}
}
static {
// so there's no need to do anything explicit here.
initIDs();
switch (StrikeCache.nativeAddressSize) {
case 8: longAddresses = true; break;
case 4: longAddresses = false; break;
default: throw new RuntimeException("Unexpected address size");
}
return null;
}
});
}
// Overridden in Windows.
return null;
}
/* Initialise ptrs used by JNI methods */
private static native void initIDs();
@SuppressWarnings("unchecked")
protected SunFontManager() {
"badfonts.txt");
if (badFontFile.exists()) {
try {
while (true) {
break;
} else {
if (FontUtilities.debugFonts()) {
name);
}
}
}
} catch (IOException e) {
try {
}
} catch (IOException ioe) {
}
}
}
* them so they are always available and preferred over
* other fonts. This needs to be registered before the
* composite fonts as otherwise some native font that
* corresponds may be found as we don't have a way to
* handle two fonts of the same name, so the JRE one
* must be the first one registered. Pass "true" to
* registerFonts method as on-screen these JRE fonts
* always go through the T2K rasteriser.
*/
if (FontUtilities.isLinux) {
/* Linux font configuration uses these fonts */
}
true, false);
/* Create the font configuration and get any font path
* that might be specified.
*/
if (isOpenJDK()) {
}
/* In prior releases the debugging font path replaced
* all normally located font directories except for the
* JRE fonts dir. This directory is still always located
* and placed at the head of the path but as an
* augmentation to the previous behaviour the
* changes below allow you to additionally append to
* the font path by starting with append: or prepend by
* starting with a prepend: sign. Eg: to append
* and to prepend
*
* If there is an appendedfontpath it in the font
* configuration it is used instead of searching the
* system for dirs.
* The behaviour of append and prepend is then similar
* to the normal case. ie it goes after what
* you prepend and * before what you append. If the
* sun.java2d.fontpath property is used, but it
* neither the append or prepend syntaxes is used then
* as except for the JRE dir the path is replaced and it
* is up to you to make sure that all the right
* directories are located. This is platform and
* locale-specific so its almost impossible to get
* right, so it should be used with caution.
*/
boolean prependToPath = false;
boolean appendToPath = false;
if (dbgFontPath != null) {
prependToPath = true;
appendToPath = true;
}
}
if (FontUtilities.debugFonts()) {
}
if (dbgFontPath != null) {
/* In debugging mode we register all the paths
* Caution: this is a very expensive call on Solaris:-
*/
if (extraFontPath != null) {
fontPath =
}
if (appendToPath) {
fontPath =
} else if (prependToPath) {
fontPath =
} else {
}
} else if (extraFontPath != null) {
/* If the font configuration contains an
* "appendedfontpath" entry, it is interpreted as a
* set of locations that should always be registered.
* It may be additional to locations normally found
* for that place, or it may be locations that need
* to have all their paths registered to locate all
* the needed platform names.
* This is typically when the same .TTF file is
* referenced from multiple font.dir files and all
* of these must be read to find all the native
* (XLFD) names for the font, so that X11 font APIs
* can be used for as many code points as possible.
*/
}
/* On Solaris, we need to register the Japanese TrueType
* directory so that we can find the corresponding
* bitmap fonts. This could be done by listing the
* directory in the font configuration file, but we
* don't want to confuse users with this quirk. There
* are no bitmap fonts for other writing systems that
* correspond to TrueType fonts and have matching XLFDs.
* We need to register the bitmap fonts only in
* environments where they're on the X font path, i.e.,
* in the Japanese locale. Note that if the X Toolkit
* is in use the font path isn't set up by JDK, but
* users of a JA locale should have it
* set up already by their login environment.
*/
}
return null;
}
});
new PrivilegedAction<Boolean>() {
}
});
if (platformFont) {
usePlatformFontMetrics = true;
}
}
/**
* This method is provided for internal and exclusive use by Swing.
*
* @param font representing a physical font.
* @return true if the underlying font is a TrueType or OpenType font
* that claims to support the Microsoft Windows encoding corresponding to
* the default file.encoding property of this JRE instance.
* This narrow value is useful for Swing to decide if the font is useful
* for the the Windows Look and Feel, or, if a composite font should be
* used instead.
* The information used to make the decision is obtained from
* the ulCodePageRange fields in the font.
* A caller can use isLogicalFont(Font) in this class before calling
* this method and would not need to call this method if that
* returns true.
*/
// static boolean fontSupportsDefaultEncoding(Font font) {
// String encoding =
// (String) java.security.AccessController.doPrivileged(
// new sun.security.action.GetPropertyAction("file.encoding"));
// if (encoding == null || font == null) {
// return false;
// }
// encoding = encoding.toLowerCase(Locale.ENGLISH);
// return FontManager.fontSupportsEncoding(font, encoding);
// }
return handle;
}
}
if (style == -1) {
}
if (!(newFont instanceof PhysicalFont)) {
}
return handle;
}
return newHandle;
}
int numMetricsSlots,
int[] exclusionRanges,
int[] exclusionMaxIndex,
boolean defer) {
exclusionMaxIndex, defer, this);
synchronized (compFonts) {
}
}
/* This variant is used only when the application specifies
* a variant of composite fonts which prefers locale specific or
* proportional fonts.
*/
int numMetricsSlots,
int[] exclusionRanges,
int[] exclusionMaxIndex,
boolean defer,
altNameCache) {
/* if the cache has an existing composite for this case, make
* its handle point to this new font.
* This ensures that when the altNameCache that is passed in
* is the global mapNameCache - ie we are running as an application -
* that any statically created java.awt.Font instances which already
* have a Font2D instance will have that re-directed to the new Font
* on subsequent uses. This is particularly important for "the"
* default font instance, or similar cases where a UI toolkit (eg
* Swing) has cached a java.awt.Font. Note that if Swing is using
* a custom composite APIs which update the standard composites have
* no effect - this is typically the case only when using the Windows
* L&F where these APIs would conflict with that L&F anyway.
*/
if (oldFont instanceof CompositeFont) {
}
}
if (FontUtilities.isLogging()) {
}
}
}
/*
* Systems may have fonts with the same name.
* We want to register only one of such fonts (at least until
* such time as there might be APIs which can accommodate > 1).
* 4) Type1 fonts, 5) native fonts.
*
* If the new font has the same name as the old font, the higher
* ranked font gets added, replacing the lower ranked one.
* If the fonts are of equal rank, then make a special case of
* font configuration rank fonts, which are on closer inspection,
* a heuristic since a font may be "larger" in the sense of more
* code points, or be a larger "file" because it has more bitmaps.
* So it is possible that using filesize may lead to less glyphs, and
* using glyphs may lead to lower quality display. Probably number
* of glyphs is the ideal, but filesize is information we already
* have and is good enough for the known cases.
* Also don't want to register fonts that match JRE font families
* but are coming from a source other than the JRE.
* This will ensure that we will algorithmically style the JRE
* plain font and get the same set of glyphs for all styles.
*
* Note that this method returns a value
* if it returns the same object as its argument that means this
* font was newly registered.
* If it returns a different object it means this font already exists,
* and you should use that one.
* If it returns null means this font was not registered and none
* in that name is registered. The caller must find a substitute
*/
// MACOSX begin -- need to access this in subclass
// MACOSX end
return null;
}
/* Don't register any font that has the same name as a composite */
return null;
}
if (FontUtilities.isLogging()) {
}
}
return f;
} else {
PhysicalFont newFont = f;
return null;
}
/* If the new font is of an equal or higher rank, it is a
* candidate to replace the current one, subject to further tests.
*/
/* All fonts initialise their mapper when first
* used. If the mapper is non-null then this font
* has been accessed at least once. In that case
* do not replace it. This may be overly stringent,
* but its probably better not to replace a font that
* someone is already using without a compelling reason.
* Additionally the primary case where it is known
* this behaviour is important is in certain composite
* fonts, and since all the components of a given
* composite are usually initialised together this
* is unlikely. For this to be a problem, there would
* have to be a case where two different composites used
* different versions of the same-named font, and they
* were initialised and used at separate times.
* In that case we continue on and allow the new font to
* be installed, but replaceFont will continue to allow
* the original font to be used in Composite fonts.
*/
return oldFont;
}
/* Normally we require a higher rank to replace a font,
* but as a special case, if the two fonts are the same rank,
* and are instances of TrueTypeFont we want the
* more complete (larger) one.
*/
if (oldFont instanceof TrueTypeFont &&
newFont instanceof TrueTypeFont) {
return oldFont;
}
} else {
return oldFont;
}
}
/* Don't replace ever JRE fonts.
* This test is in case a font configuration references
* a Lucida font, which has been mapped to a Lucida
* from the host O/S. The assumption here is that any
* such font configuration file is probably incorrect, or
* the host O/S version is for the use of AWT.
* In other words if we reach here, there's a possible
* problem with our choice of font configuration fonts.
*/
if (FontUtilities.isLogging()) {
.warning("Unexpected attempt to replace a JRE " +
}
return oldFont;
}
if (FontUtilities.isLogging()) {
}
newFont);
}
return newFont;
} else {
return oldFont;
}
}
}
return regFonts;
}
}
/* The class FontRegistrationInfo is used when a client says not
* to register a font immediately. This mechanism is used to defer
* initialisation of all the components of composite fonts at JRE
* start-up. The CompositeFont class is "aware" of this and when it
* is first used it asks for the registration of its components.
* Also in the event that any physical font is requested the
* deferred fonts are initialised before triggering a search of the
* system.
* Two maps are used. One to track the deferred fonts. The
* other to track the fonts that have been initialised through this
* mechanism.
*/
private static final class FontRegistrationInfo {
int fontFormat;
boolean javaRasterizer;
int fontRank;
boolean useJavaRasterizer, int rank) {
this.fontFilePath = fontPath;
this.nativeNames = names;
this.fontFormat = format;
this.javaRasterizer = useJavaRasterizer;
}
}
/* Remind: possibly enhance initialiseDeferredFonts() to be
* optionally given a name and a style and it could stop when it
* finds that font - but this would be a problem if two of the
* fonts reference the same font face name (cf the Solaris
* euro fonts).
*/
protected synchronized void initialiseDeferredFonts() {
}
}
}
}
}
}
/* We keep a map of the files which contain the Lucida fonts so we
* don't need to search for them.
* But since we know what fonts these files contain, we can also avoid
* opening them to look for a font name we don't recognise - see
* findDeferredFont().
* For typical cases where the font isn't a JRE one the overhead is
* this method call, HashMap.get() and null reference test, then
* a boolean test of noOtherJREFontFiles.
*/
public
if (physicalFont != null &&
return physicalFont;
}
}
}
/* Iterate over the deferred font files looking for any in the
* jre directory that we didn't recognise, open each of these.
* In almost all installations this will quickly fall through
* because only the Lucidas will be present and jreOtherFontFiles
* will be empty.
* noOtherJREFontFiles is used so we can skip this block as soon
* as its determined that its not needed - almost always after the
* very first time through.
*/
if (noOtherJREFontFiles) {
return null;
}
synchronized (jreLucidaFontFiles) {
if (jreOtherFontFiles == null) {
/* skip names which aren't absolute, aren't in the JRE
* directory, or are known Lucida fonts.
*/
continue;
}
}
noOtherJREFontFiles = true;
}
}
fileName = jreOtherFontFiles[i];
continue;
}
jreOtherFontFiles[i] = null;
if (physicalFont != null &&
return physicalFont;
}
}
}
return null;
}
/* This skips JRE installed fonts. */
continue;
}
if (physicalFont != null &&
return physicalFont;
}
}
return null;
}
if (physicalFont != null) {
return physicalFont;
} else {
}
}
int fontFormat,
boolean useJavaRasterizer,
int fontRank) {
}
public synchronized
if (fileNameKey == null) {
return null;
}
if (FontUtilities.isLogging()) {
}
if (physicalFont != null) {
/* Store the handle, so that if a font is bad, we
* retrieve the substituted font.
*/
} else {
}
} else {
/* Probably shouldn't happen, but just in case */
} else {
}
}
return physicalFont;
}
}
}
/* Note that the return value from this method is not always
* derived from this file, and may be null. See addToFontList for
* some explanation of this.
*/
int fontFormat,
boolean useJavaRasterizer,
int fontRank) {
return regFont;
}
try {
switch (fontFormat) {
case FONTFORMAT_TRUETYPE:
int fn = 0;
do {
if (physicalFont == null) {
physicalFont = pf;
}
}
break;
case FONTFORMAT_TYPE1:
break;
case FONTFORMAT_NATIVE:
default:
}
if (FontUtilities.isLogging()) {
}
} catch (FontFormatException ffe) {
if (FontUtilities.isLogging()) {
}
}
if (physicalFont != null &&
fontFormat != FONTFORMAT_NATIVE) {
}
return physicalFont;
}
String[][] nativeNames,
int fontCount,
int fontFormat,
boolean useJavaRasterizer,
for (int i=0; i < fontCount; i++) {
if (defer) {
} else {
}
}
}
/*
* This is the Physical font used when some other font on the system
* can't be located. There has to be at least one font or the font
* system is not useful and the graphics environment cannot sustain
* the Java platform.
*/
if (defaultPhysicalFont == null) {
/* findFont2D will load all fonts before giving up the search.
* If the JRE Lucida isn't found (eg because the JRE fonts
* directory is missing), it could find another version of Lucida
* from the host system. This is OK because at that point we are
* misconfiguration and this is probably a reasonable substitution.
*/
if (defaultPhysicalFont == null) {
}
if (defaultPhysicalFont == null) {
/* Because of the findFont2D call above, if we reach here, we
* know all fonts have already been loaded, just accept any
* match at this point. If this fails we are in real trouble
* and I don't know how to recover from there being absolutely
* no fonts anywhere on the system.
*/
if (i.hasNext()) {
} else {
throw new Error("Probable fatal error:No fonts found.");
}
}
}
return defaultPhysicalFont;
}
}
/*
* return String representation of style prepended with "."
* This is useful for performance to avoid unnecessary string operations.
*/
switch(num){
return ".bold";
return ".italic";
return ".bolditalic";
default:
return ".plain";
}
}
/* This is implemented only on windows and is called from code that
* executes only on windows. This isn't pretty but its not a precedent
* in this file. This very probably should be cleaned up at some point.
*/
protected void
}
/* Obtained from Platform APIs (windows only)
* Map from lower-case font full name to basename of font file.
* Eg "arial bold" -> ARIALBD.TTF.
* For TTC files, there is a mapping for each font in the file.
*/
/* Obtained from Platform APIs (windows only)
* Map from lower-case font full name to the name of its font family
* Eg "arial bold" -> "Arial"
*/
/* Obtained from Platform APIs (windows only)
* Map from a lower-case family name to a list of full names of
* the member fonts, eg:
* "arial" -> ["Arial", "Arial Bold", "Arial Italic","Arial Bold Italic"]
*/
/* The directories which contain platform fonts */
private boolean haveCheckedUnreferencedFontFiles;
final FilenameFilter filter;
if (noType1) {
} else {
filter = new TTorT1Filter();
}
return new String[0];
}
}
return files;
} else {
continue;
}
}
}
}
}
});
}
/* This is needed since some windows registry names don't match
* the font names.
* - UPC styled font names have a double space, but the
* registry entry mapping to a file doesn't.
* - Marlett is in a hidden file not listed in the registry
* - The registry advertises that the file david.ttf contains a
* font with the full name "David Regular" when in fact its
* just "David".
* Directly fix up these known cases as this is faster.
* If a font which doesn't match these known cases has no file,
* it may be a font that has been temporarily added to the known set
* or it may be an installed font with a missing registry entry.
* Installed fonts are those in the windows font directories.
* Make a best effort attempt to locate these.
* We obtain the list of TrueType fonts in these directories and
* filter out all the font files we already know about from the registry.
* What remains may be "bad" fonts, duplicate fonts, or perhaps the
* missing font(s) we are looking for.
* Open each of these files to find out.
*/
private void resolveWindowsFonts() {
/* If this name exists and isn't for a valid name
* replace the mapping to the file with this font
*/
}
}
} else {
if (unmappedFontNames == null) {
}
}
}
}
if (unmappedFontNames != null) {
/* Every font key in fontToFileMap ought to correspond to a
* font key in fontToFamilyNameMap. Entries that don't seem
* to correspond are likely fonts that were named differently
* by GDI than in the registry. One known cause of this is when
* Windows has had its regional settings changed so that from
* GDI we get a localised (eg Chinese or Japanese) name for the
* font, but the registry retains the English version of the name
* that corresponded to the "install" locale for windows.
* Since we are in this code block because there are unmapped
* font names, we can look to find unused font->file mappings
* and then open the files to read the names. We don't generally
* want to open font files, as its a performance hit, but this
* occurs only for a small number of fonts on specific system
* configs - ie is believed that a "true" Japanese windows would
* have JA names in the registry too.
* Clone fontToFileMap and remove from the clone all keys which
* match a fontToFamilyNameMap key. What remains maps to the
* files we want to open to find the fonts GDI returned.
* A font in such a file is added to the fontToFileMap after
* checking its one of the unmappedFontNames we are looking for.
* The original name that didn't map is removed from fontToFileMap
* so essentially this "fixes up" fontToFileMap to use the same
* name as GDI.
* Also note that typically the fonts for which this occurs in
* CJK locales are TTC fonts and not all fonts in a TTC may have
* localised names. Eg MSGOTHIC.TTC contains 3 fonts and one of
* them "MS UI Gothic" has no JA name whereas the other two do.
* So not every font in these files is unmapped or new.
*/
}
}
/* If there are still unmapped font names, this means there's
* something that wasn't in the registry. We need to get all
* the font files directly and look at the ones that weren't
* found in the registry.
*/
/* getFontFilesFromPath() returns all lower case names.
* To compare we also need lower case
* versions of the names from the registry.
*/
}
/* We don't look for Type1 files here as windows will
* not enumerate these, so aren't useful in reconciling
* GDI's unmapped files. We do find these later when
* we enumerate all fonts.
*/
}
}
}
/* remove from the set of names that will be returned to the
* user any fonts that can't be mapped to files.
*/
for (int i=0; i<sz; i++) {
if (familyName != null) {
}
}
}
if (FontUtilities.isLogging()) {
}
}
}
}
}
/**
* In some cases windows may have fonts in the fonts folder that
* don't show up in the registry or in the GDI calls to enumerate fonts.
* The only way to find these is to list the directory. We invoke this
* only in getAllFonts/Families, so most searches for a specific
* additional hit of listing the directory. This hit is small enough
* that its not significant in these 'enumerate all the fonts' cases.
* The basic approach is to cross-reference the files windows found
* with the ones in the directory listing approach, and for each
* in the latter list that is missing from the former list, register it.
*/
private synchronized void checkForUnreferencedFontFiles() {
return;
}
haveCheckedUnreferencedFontFiles = true;
if (!FontUtilities.isWindows) {
return;
}
/* getFontFilesFromPath() returns all lower case names.
* To compare we also need lower case
* versions of the names from the registry.
*/
}
/* To avoid any issues with concurrent modification, create
* copies of the existing maps, add the new fonts into these
* and then replace the references to the old ones with the
* new maps. ConcurrentHashmap is another option but its a lot
* more changes and with this exception, these maps are intended
* to be static.
*/
if (FontUtilities.isLogging()) {
}
if (f == null) {
continue;
}
if (fontToFileMap2 == null) {
familyToFontListMap2 = new
}
} else {
}
}
}
if (fontToFileMap2 != null) {
}
}
try {
int fn = 0;
if (FontUtilities.isLogging()) {
}
do {
// prefer the font's locale name.
if (FontUtilities.isLogging()) {
.info("Resolved absent registry entry for " +
}
}
}
} catch (Exception e) {
}
}
}
/* Hardwire the English names and expected file names of fonts
* commonly used at start up. Avoiding until later even the small
* cost of calling platform APIs to locate these can help.
* The code that registers these fonts needs to "bail" if any
* of the files do not exist, so it will verify the existence of
* all non-null file names first.
* They are added in to a map with nominally the first
* word in the name of the family as the key. In all the cases
* we are using the the family name is a single word, and as is
* more or less required the family name is the initial sequence
* in a full name. So lookup first finds the matching description,
* then registers the whole family, returning the right font.
*/
public static class FamilyDescription {
}
/**
* default implementation does nothing.
*/
}
if (platformFontMap == null) {
}
return null;
}
if (spaceIndex > 0) {
}
return null;
}
/* Once we've established that its at least the first word,
* we need to dig deeper to make sure its a match for either
* a full name, or the family name, to make sure its not
* a request for some other font that just happens to start
* with the same first word.
*/
int styleIndex = -1;
styleIndex = 0;
styleIndex = 1;
styleIndex = 2;
styleIndex = 3;
}
return null;
}
boolean failure = false;
/* In a terminal server config, its possible that getPathName()
* will return null, if the file doesn't exist, hence the null
* checks on return. But in the normal client config we need to
* follow this up with a check to see if all the files really
* exist for the non-null paths.
*/
failure = true;
}
}
failure = true;
}
}
if (italicFile == null) {
failure = true;
}
}
if (boldItalicFile == null) {
failure = true;
}
}
if (failure) {
if (FontUtilities.isLogging()) {
}
return null;
}
/* Some of these may be null,as not all styles have to exist */
continue;
}
if (!f.exists()) {
}
}
}
});
if (failure) {
if (FontUtilities.isLogging()) {
}
return null;
}
/* If we reach here we know that we have all the files we
* expect, so all should be fine so long as the contents
* are what we'd expect. Now on to registering the fonts.
* Currently this code only looks for TrueType fonts, so format
* and rank can be specified without looking at the filename.
*/
continue;
}
if (f == styleIndex) {
}
}
/* Two general cases need a bit more work here.
* 1) If font is null, then it was perhaps a request for a
* non-existent font, such as "Tahoma Italic", or a family name -
* where family and full name of the plain font differ.
* Fall back to finding the closest one in the family.
* This could still fail if a client specified "Segoe" instead of
* "Segoe UI".
* 2) The request is of the form "MyFont Bold", style=Font.ITALIC,
* and so we want to see if there's a Bold Italic font, or
* "MyFamily", style=Font.BOLD, and we may have matched the plain,
* but now need to revise that to the BOLD font.
*/
if (fontFamily != null) {
}
}
}
}
return font;
}
if (fontToFileMap == null) {
if (FontUtilities.isWindows) {
}
if (FontUtilities.isLogging()) {
}
}
return fontToFileMap;
}
private void logPlatformFontInfo() {
}
}
}
}
}
/* Note this return list excludes logical fonts and JRE fonts */
return null;
}
/* This odd code with TreeMap is used to preserve a historical
* behaviour wrt the sorting order .. */
for (String s : a) {
}
}
}
public boolean gotFontsFromPlatform() {
}
}
int fontFormat = FONTFORMAT_NONE;
} else if
}
if (fontFormat == FONTFORMAT_NONE) {
return null;
}
}
return null;
}
/* Used to register any font files that are found by platform APIs
* that weren't previously found in the standard font locations.
* the isAbsolute() check is needed since that's whats stored in the
* set, and on windows, the fonts in the system font directory that
* are in the fontToFileMap are just basenames. We don't want to try
* to register those again, but we do want to register other registry
* installed fonts.
*/
return;
}
}
}
public boolean
return false;
}
}
return true;
}
/* Path may be absolute or a base file name relative to one of
* the platform font directories
*/
if (f.isAbsolute()) {
return s;
} else {
if (f.exists()) {
return f.getAbsolutePath();
}
}
return null;
}
});
return path;
}
}
return s; // shouldn't happen, but harmless
}
/* lcName is required to be lower case for use as a key.
* lcName may be a full name, or a family name, and style may
* be specified in addition to either of these. So be sure to
* get the right one. Since an app *could* ask for "Foo Regular"
* and later ask for "Foo Italic", if we don't register all the
* styles, then logic in findFont2D may try to style the original
* so we register the entire family if we get a match here.
* This is still a big win because this code is invoked where
* otherwise we would register all fonts.
* It's also useful for the case where "Foo Bold" was specified with
* style Font.ITALIC, as we would want in that case to try to return
* "Foo Bold Italic" if it exists, and it is only by locating "Foo Bold"
* and opening it that we really "know" it's Bold, and can look for
* a font that supports that and the italic style.
* The code in here is not overtly windows-specific but in fact it
* is unlikely to be useful as is on other platforms. It is maintained
* in this shared source file to be close to its sole client and
* because so much of the logic is intertwined with the logic in
* findFont2D.
*/
return null;
}
if (familyName != null) {
} else {
if (lcFontName != null) {
}
}
}
return null;
}
return null;
}
/* first check that for every font in this family we can find
* a font file. The specific reason for doing this is that
* in at least one case on Windows a font has the face name "David"
* but the registry entry is "David Regular". That is the "unique"
* name of the font but in other cases the registry contains the
* "full" name. See the specifications of name ids 3 and 4 in the
* TrueType 'name' table.
* In general this could cause a problem that we fail to register
* if we all members of a family that we may end up mapping to
* the wrong font member: eg return Bold when Plain is needed.
*/
if (FontUtilities.isLogging()) {
.info("Platform lookup : No file for font " +
}
return null;
}
}
/* Currently this code only looks for TrueType fonts, so format
* and rank can be specified without looking at the filename.
*/
FONTFORMAT_TRUETYPE, false,
}
/* Register all fonts in this family. */
continue;
}
/* Currently this code only looks for TrueType fonts, so format
* and rank can be specified without looking at the filename.
*/
}
/* Handle case where request "MyFont Bold", style=Font.ITALIC */
if (physicalFont != null) {
}
if (fontFamily != null) {
}
}
return font;
}
/*
* The client supplies a name and a style.
* The name could be a family name, or a full name.
* A font may exist with the specified style, or it may
* exist only in some other style. For non-native fonts the scaler
* may be able to emulate the required style.
*/
/* If preferLocaleFonts() or preferProportionalFonts() has been
* called we may be using an alternate set of composite fonts in this
* app context. The presence of a pre-built name map indicates whether
* this is so, and gives access to the alternate composite for the
* name.
*/
if (altNameCache != null) {
} else {
}
} else {
}
return font;
}
if (FontUtilities.isLogging()) {
}
// The check below is just so that the bitmap fonts being set by
// AWT and Swing thru the desktop properties do not trigger the
// the load fonts case. The two bitmap fonts are now mapped to
// appropriate equivalents for serif and sansserif.
// Note that the cost of this comparison is only for the first
// call until the map is filled.
if (FontUtilities.isWindows) {
name = "sansserif";
name = "serif";
}
}
/* This isn't intended to support a client passing in the
* string default, but if a client passes in null for the name
* the java.awt.Font class internally substitutes this name.
* So we need to recognise it here to prevent a loadFonts
* on the unrecognised name. The only potential problem with
* this is it would hide any real font called "default"!
* But that seems like a potential problem we can ignore for now.
*/
name = "dialog";
}
/* First see if its a family name. */
}
}
}
return font;
}
}
/* If it wasn't a family name, it should be a full name of
* either a composite, or a physical font
*/
/* Check that the requested style matches the matched font's style.
* But also match style automatically if the requested style is
* "plain". This because the existing behaviour is that the fonts
* listed via getAllFonts etc always list their style as PLAIN.
* This does lead to non-commutative behaviours where you might
* start with "Lucida Sans Regular" and ask for a BOLD version
* and get "Lucida Sans DemiBold" but if you ask for the PLAIN
* style of "Lucida Sans DemiBold" you get "Lucida Sans DemiBold".
* This consistent however with what happens if you have a bold
* version of a font and no plain version exists - alg. styling
* doesn't "unbolden" the font.
*/
return font;
} else {
/* If it was a full name like "Lucida Sans Regular", but
* the style requested is "bold", then we want to see if
* there's the appropriate match against another font in
* that family before trying to load all fonts, or applying a
* algorithmic styling
*/
/* We exactly matched the requested style, use it! */
if (familyFont != null) {
return familyFont;
} else {
/* This next call is designed to support the case
* where bold italic is requested, and if we must
* style, then base it on either bold or italic -
* not on plain!
*/
if (familyFont != null) {
/* The next check is perhaps one
* that shouldn't be done. ie if we get this
* far we have probably as close a match as we
* are going to get. We could load all fonts to
* see if somehow some parts of the family are
* loaded but not all of it.
*/
return familyFont;
}
}
}
}
}
}
if (FontUtilities.isWindows) {
if (FontUtilities.isLogging()) {
}
return font;
}
/* Don't want Windows to return a Lucida Sans font from
* C:\Windows\Fonts
*/
return font;
}
}
if (FontUtilities.isLogging()) {
.info("Found font via platform API for request:\"" +
" found font: " + font);
}
return font;
}
}
/* If reach here and no match has been located, then if there are
* uninitialised deferred fonts, load as many of those as needed
* to find the deferred font. If none is found through that
* search continue on.
* There is possibly a minor issue when more than one
* deferred font implements the same font face. Since deferred
* fonts are only those in font configuration files, this is a
* controlled situation, the known case being Solaris euro_fonts
* versions of Arial, Times New Roman, Courier New. However
* the larger font will transparently replace the smaller one
* - see addToFontList() - when it is needed by the composite font.
*/
return font;
}
}
/* Some apps use deprecated 1.0 names such as helvetica and courier. On
* If running on Solaris will register all the fonts in this
* directory.
* May as well register the whole directory without actually testing
* the font name is one of the deprecated names as the next step would
* load all fonts which are in this directory anyway.
* In the event that this lookup is successful it potentially "hides"
* TrueType versions of such fonts that are elsewhere but since they
* do not exist on Solaris this is not a problem.
* Set a flag to indicate we've done this registration to avoid
* repetition and more seriously, to avoid recursion.
*/
/* "timesroman" is a special case since that's not the
* name of any known font on Solaris or elsewhere.
*/
}
loaded1dot0Fonts = true;
return ff;
}
/* We check for application registered fonts before
* explicitly loading all fonts as if necessary the registration
* code will have done so anyway. And we don't want to needlessly
* load the actual files for all fonts.
* Just as for installed fonts we check for family before fullname.
* We do not add these fonts to fontNameCache for the
* app context case which eliminates the overhead of a per context
* cache for these.
*/
if (fontsAreRegistered) {
} else {
}
}
}
if (fontsAreRegistered) {
}
return font;
}
}
if (fontsAreRegistered) {
}
return font;
}
}
/* If reach here and no match has been located, then if all fonts
* are not yet loaded, do so, and then recurse.
*/
if (!loadedAllFonts) {
if (FontUtilities.isLogging()) {
}
loadFonts();
loadedAllFonts = true;
}
if (!loadedAllFontFiles) {
if (FontUtilities.isLogging()) {
}
loadedAllFontFiles = true;
}
* whatever is the default in this locale. This is the way it always
* has been but may be surprising to some developers if "Arial Regular"
* were hard-coded in their app and yet "Arial Regular" was not the
* default name. Fortunately for them, as a consequence of the JDK
* supporting returning names and family names for arbitrary locales,
* we also need to support searching all localised names for a match.
* But because this case of the name used to reference a font is not
* the same as the default for this locale is rare, it makes sense to
* search a much shorter list of default locale names and only go to
* a longer list of names in the event that no match was found.
* So add here code which searches localised names too.
* As in 1.4.x this happens only after loading all fonts, which
* is probably the right order.
*/
return font;
}
/* Perhaps its a "compatibility" name - timesroman, helvetica,
* or courier, which 1.0 apps used for logical fonts.
* We look for these "late" after a loadFonts as we must not
* hide real fonts of these names.
* Map these appropriately:
* On windows this means according to the rules specified by the
* FontConfiguration : do it only for encoding==Cp1252
*
* REMIND: this is something we plan to remove.
*/
if (FontUtilities.isWindows) {
if (compatName != null) {
return font;
}
return font;
return font;
return font;
}
if (FontUtilities.isLogging()) {
}
switch (fallback) {
case PHYSICAL_FALLBACK: return getDefaultPhysicalFont();
default: return null;
}
}
/*
* Workaround for apps which are dependent on a font metrics bug
* in JDK 1.1. This is an unsupported win32 private setting.
* Left in for a customer - do not remove.
*/
public boolean usePlatformFontMetrics() {
return usePlatformFontMetrics;
}
public int getNumFonts() {
}
}
// MACOSX begin -- need to access this in subclass
// MACOSX end
throws FontFormatException {
try {
switch (fontFormat) {
case Font.TRUETYPE_FONT:
break;
case Font.TYPE1_FONT:
break;
default:
throw new FontFormatException("Unrecognised Font Format");
}
} catch (FontFormatException e) {
if (isCopy) {
}
return null;
}
});
}
throw(e);
}
if (isCopy) {
synchronized (FontManager.class) {
if (tmpFontFiles == null) {
}
if (fileCloser == null) {
public void run() {
for (int i=0;i<CHANNELPOOLSIZE;i++) {
if (fontFileCache[i] != null) {
try {
fontFileCache[i].close();
} catch (Exception e) {
}
}
}
if (tmpFontFiles != null) {
try {
} catch (Exception e) {
}
}
}
return null;
}
});
}
};
/* The thread must be a member of a thread group
* which will not get GCed before VM exit.
* Make its parent the top-level thread group.
*/
return null;
}
});
}
}
}
return font2D;
}
/* remind: used in X11GraphicsEnvironment and called often enough
* that we ought to obsolete this code
*/
}
}
return null;
}
/*
* It designed to be called (for example) by the font scaler
* when in processing a font file it is discovered to be incorrect.
* This is different than the case where fonts are discovered to
* be incorrect during initial verification, as such fonts are
* never registered.
* Handles to this font held are re-directed to a default font.
* This default may not be an ideal substitute buts it better than
* crashing This code assumes a PhysicalFont parameter as it doesn't
* make sense for a Composite to be "bad".
*/
if (!(font2D instanceof PhysicalFont)) {
/* We should never reach here, but just in case */
return;
} else {
if (FontUtilities.isLogging()) {
}
}
}
/*
* This encapsulates all the work that needs to be done when a
* Font2D is replaced by a different Font2D.
*/
/* already done */
return;
}
/* If we try to replace the font with itself, that won't work,
* so pick any alternative physical font
*/
if (FontUtilities.isLogging()) {
}
break;
}
}
if (FontUtilities.isLogging()) {
.severe("This is bad. No good physicalFonts found.");
}
return;
}
}
/* eliminate references to this font, so it won't be located
* by future callers, and will be eligible for GC when all
* references are removed
*/
if (localeFullNamesToFont != null) {
/* Should I be replacing these, or just I just remove
* the names from the map?
*/
try {
} catch (Exception e) {
/* some maps don't support this operation.
* In this case just give up and remove the entry.
*/
}
}
}
}
for (int i=0; i<maxCompFont; i++) {
/* Deferred initialization of composites shouldn't be
* a problem for this case, since a font must have been
* initialised to be discovered to be bad.
* Some JRE composites on Solaris use two versions of the same
* font. The replaced font isn't bad, just "smaller" so there's
* no need to make the slot point to the new font.
* Since composites have a direct reference to the Font2D (not
* via a handle) making this substitution is not safe and could
* cause an additional problem and so this substitution is
* warranted only when a font is truly "bad" and could cause
* a crash. So we now replace it only if its being substituted
* with some font other than a fontconfig rank font
* Since in practice a substitution will have the same rank
* this may never happen, but the code is safer even if its
* also now a no-op.
* The only obvious "glitch" from this stems from the current
* implementation that when asked for the number of glyphs in a
* composite it lies and returns the number in slot 0 because
* composite glyphs aren't contiguous. Since we live with that
* we can live with the glitch that depending on how it was
* initialised a composite may return different values for this.
* Fixing the issues with composite glyph ids is tricky as
* there are exclusion ranges and unlike other fonts even the
* true "numGlyphs" isn't a contiguous range. Likely the only
* solution is an API that returns an array of glyph ranges
* which takes precedence over the existing API. That might
* also need to address excluding ranges which represent a
* code point supported by an earlier component.
*/
}
}
}
private synchronized void loadLocaleNames() {
if (localeFullNamesToFont != null) {
return;
}
if (fonts[i] instanceof TrueTypeFont) {
}
}
}
}
}
/* This replicate the core logic of findFont2D but operates on
* all the locale names. This hasn't been merged into findFont2D to
* keep the logic simpler and reduce overhead, since this case is
* almost never used. The main case in which it is called is when
* a bogus font name is used and we need to check all possible names
* before returning the default case.
*/
if (FontUtilities.isLogging()) {
}
/* If reach here and no match has been located, then if we have
* not yet built the map of localeFullNamesToFont for TT fonts, do so
* now. This method must be called after all fonts have been loaded.
*/
if (localeFullNamesToFont == null) {
}
/* First see if its a family name. */
}
return font;
}
}
/* If it wasn't a family name, it should be a full name. */
synchronized (this) {
}
return font;
} else {
/* We exactly matched the requested style, use it! */
if (familyFont != null) {
return familyFont;
} else {
if (familyFont != null) {
/* The next check is perhaps one
* that shouldn't be done. ie if we get this
* far we have probably as close a match as we
* are going to get. We could load all fonts to
* see if somehow some parts of the family are
* loaded but not all of it.
* This check is commented out for now.
*/
familyFont = null;
}
return familyFont;
}
}
}
}
}
return font;
}
/* Supporting "alternate" composite fonts on 2D graphics objects
* is accessed by the application by calling methods on the local
* GraphicsEnvironment. The overall implementation is described
* in one place, here, since otherwise the implementation is spread
* around it may be difficult to track.
* The methods below call into SunGraphicsEnvironment which creates a
* new FontConfiguration instance. The FontConfiguration class,
* and its platform sub-classes are updated to take parameters requesting
* these behaviours. This is then used to create new composite font
* instances. Since this calls the initCompositeFont method in
* SunGraphicsEnvironment it performs the same initialization as is
* performed normally. There may be some duplication of effort, but
* that code is already written to be able to perform properly if called
* to duplicate work. The main difference is that if we detect we are
* are not placed in the "default" maps but into an AppContext instance.
* The font lookup mechanism in java.awt.Font.getFont2D() is also updated
* so that look-up for composite fonts will in that case always
* do a lookup rather than returning a cached result.
* This is inefficient but necessary else singleton java.awt.Font
* instances would not retrieve the correct Font2D for the appcontext.
* sun.font.FontManager.findFont2D is also updated to that it uses
* a name map cache specific to that appcontext.
*
* Getting an AppContext is expensive, so there is a global variable
* that records whether these methods have ever been called and can
* avoid the expense for almost all applications. Once the correct
* CompositeFont is associated with the Font, everything should work
* through existing mechanisms.
* A special case is that GraphicsEnvironment.getAllFonts() must
* return an AppContext specific list.
*
* Calling the methods below is "heavyweight" but it is expected that
* these methods will be called very rarely.
*
* If _usingPerAppContextComposites is true, we are in "applet"
* (eg browser) enviroment and at least one context has selected
* an alternate composite font behaviour.
* If _usingAlternateComposites is true, we are not in an "applet"
* environment and the (single) application has selected
* an alternate composite font behaviour.
*
* - Printing: The implementation delegates logical fonts to an AWT
* mechanism which cannot use these alternate configurations.
* We can detect that alternate fonts are in use and back-off to 2D, but
* that uses outlines. Much of this can be fixed with additional work
* but that may have to wait. The results should be correct, just not
* optimal.
*/
private boolean _usingPerAppContextComposites = false;
private boolean _usingAlternateComposites = false;
/* These values are used only if we are running as a standalone
* application, as determined by maybeMultiAppContext();
*/
private static boolean gAltJAFont = false;
private boolean gLocalePref = false;
private boolean gPropPref = false;
/* This method doesn't check if alternates are selected in this app
* context. Its used by the FontMetrics caching code which in such
* a case cannot retrieve a cached metrics solely on the basis of
* the Font.equals() method since it needs to also check if the Font2D
* is the same.
* We also use non-standard composites for Swing native L&F fonts on
* Windows. In that case the policy is that the metrics reported are
* based solely on the physical font in the first slot which is the
* visible java.awt.Font. So in that case the metrics cache which tests
* the Font does what we want. In the near future when we expand the GTK
* logical font definitions we may need to revisit this if GTK reports
* combined metrics instead. For now though this test can be simple.
*/
public boolean maybeUsingAlternateCompositeFonts() {
}
public boolean usingAlternateCompositeFonts() {
return (_usingAlternateComposites ||
}
private static boolean maybeMultiAppContext() {
return new Boolean
}
});
return appletSM.booleanValue();
}
/* Modifies the behaviour of a subsequent call to preferLocaleFonts()
* to use Mincho instead of Gothic for dialoginput in JA locales
* on windows. Not needed on other platforms.
*/
public synchronized void useAlternateFontforJALocales() {
if (FontUtilities.isLogging()) {
.info("Entered useAlternateFontforJALocales().");
}
if (!FontUtilities.isWindows) {
return;
}
if (!maybeMultiAppContext()) {
gAltJAFont = true;
} else {
}
}
public boolean usingAlternateFontforJALocales() {
if (!maybeMultiAppContext()) {
return gAltJAFont;
} else {
}
}
public synchronized void preferLocaleFonts() {
if (FontUtilities.isLogging()) {
}
/* Test if re-ordering will have any effect */
if (!FontConfiguration.willReorderForStartupLocale()) {
return;
}
if (!maybeMultiAppContext()) {
if (gLocalePref == true) {
return;
}
gLocalePref = true;
_usingAlternateComposites = true;
} else {
return;
}
boolean acPropPref =
/* If there is an existing hashtable, we can drop it. */
_usingPerAppContextComposites = true;
}
}
public synchronized void preferProportionalFonts() {
if (FontUtilities.isLogging()) {
.info("Entered preferProportionalFonts().");
}
/* If no proportional fonts are configured, there's no need
* to take any action.
*/
if (!FontConfiguration.hasMonoToPropMap()) {
return;
}
if (!maybeMultiAppContext()) {
if (gPropPref == true) {
return;
}
gPropPref = true;
_usingAlternateComposites = true;
} else {
return;
}
boolean acLocalePref =
/* If there is an existing hashtable, we can drop it. */
_usingPerAppContextComposites = true;
}
}
if (installedNames == null) {
Locale l = getSystemStartupLocale();
}
}
}
return installedNames;
}
/* Keys are used to lookup per-AppContext Hashtables */
private boolean fontsAreRegistered = false;
private boolean fontsAreRegisteredPerAppContext = false;
/* This method should not be called with "null".
* It is the caller's responsibility to ensure that.
*/
return false;
}
/* Initialise these objects only once we start to use this API */
synchronized (regFamilyKey) {
if (createdByFamilyName == null) {
}
}
return false;
}
/* We want to ensure that this font cannot override existing
* installed fonts. Check these conditions :
* - family name is not that of an installed font
* - full name is not that of an installed font
* - family name is not the same as the full name of an installed font
* - full name is not the same as the family name of an installed font
* The last two of these may initially look odd but the reason is
* that (unfortunately) Font constructors do not distinuguish these.
* An extreme example of such a problem would be a font which has
* family name "Dialog.Plain" and full name of "Dialog".
* The one arguably overly stringent restriction here is that if an
* application wants to supply a new member of an existing family
* It will get rejected. But since the JRE can perform synthetic
* styling in many cases its not necessary.
* We don't apply the same logic to registered fonts. If apps want
* to do this lets assume they have a reason. It won't cause problems
* except for themselves.
*/
Locale l = getSystemStartupLocale();
return false;
}
/* Checks passed, now register the font */
if (!maybeMultiAppContext()) {
fontsAreRegistered = true;
} else {
if (familyTable == null) {
}
fontsAreRegisteredPerAppContext = true;
}
/* Create the FontFamily and add font to the tables */
}
/* Remove name cache entries if not using app contexts.
* To accommodate a case where code may have registered first a plain
* family member and then used it and is now registering a bold family
* member, we need to remove all members of the family, so that the
* new style can get picked up rather than continuing to synthesise.
*/
if (fontsAreRegistered) {
}
return true;
}
/* Remove from the name cache all references to the Font2D */
return;
}
}
}
}
// It may look odd to use TreeMap but its more convenient to the caller.
if (fontsAreRegistered) {
} else if (fontsAreRegisteredPerAppContext) {
} else {
return null;
}
Locale l = getSystemStartupLocale();
synchronized (familyTable) {
}
}
return map;
}
}
if (fontsAreRegistered) {
} else if (fontsAreRegisteredPerAppContext) {
} else {
return null;
}
Locale l = getSystemStartupLocale();
synchronized (nameTable) {
int i=0;
}
return fonts;
}
}
/* First check if we already initialised path dirs */
return pathDirs;
}
try {
while (parser.hasMoreTokens()) {
}
} catch (NoSuchElementException e) {
}
return pathDirs;
}
/**
* Returns an array of two strings. The first element is the
* name of the font. The second element is the file name.
*/
// Begin: Refactored from SunGraphicsEnviroment.
/*
* helper function for registerFonts
*/
int fontFormat, boolean useJavaRasterizer,
int fontRank,
boolean defer, boolean resolveSymLinks) {
return;
}
int fontCount = 0;
if (resolveSymLinks) {
try {
} catch (IOException e) {
}
}
}
// REMIND: case compare depends on platform
continue;
}
if (FontUtilities.debugFonts()) {
}
continue; // skip this font file.
}
if (FontUtilities.debugFonts()
message += " with no native name";
} else {
}
}
}
}
return;
}
return null;
}
/**
* Returns a file name for the physical font represented by this platform
* font name. The default implementation tries to obtain the file name
* from the font configuration.
* Subclasses may override to provide information from other sources.
*/
}
/**
* Return the default font configuration.
*/
return fontConfig;
}
/* A call to this method should be followed by a call to
* registerFontDirs(..)
*/
}
return fontPath;
}
public static boolean isOpenJDK() {
return FontUtilities.isOpenJDK;
}
protected void loadFonts() {
if (discoveredAllFonts) {
return;
}
/* Use lock specific to the font system */
synchronized (this) {
if (FontUtilities.debugFonts()) {
.info("SunGraphicsEnvironment.loadFonts() called");
}
}
// this will find all fonts including those already
// registered. But we have checks in place to prevent
// double registration.
if (! gotFontsFromPlatform()) {
registerFontsOnPath(fontPath, false,
false, true);
loadedAllFontFiles = true;
}
}
discoveredAllFonts = true;
return null;
}
});
}
}
return;
}
boolean useJavaRasterizer, int fontRank,
boolean defer, boolean resolveSymLinks) {
try {
while (parser.hasMoreTokens()) {
}
} catch (NoSuchElementException e) {
}
}
/* Called to register fall back fonts */
}
// MACOSX begin -- need to access this in subclass
// MACOSX end
int fontRank,
boolean defer, boolean resolveSymLinks) {
}
}
/**
* Returns file name for default font, either absolute
* or relative as needed by registerFontFile.
*/
if (defaultFontFileName == null) {
}
return defaultFontFileName;
}
private void initDefaultFonts() {
if (!isOpenJDK()) {
if (useAbsoluteFontFileNames()) {
} else {
}
}
}
/**
* Whether registerFontFile expects absolute or relative
* font file names.
*/
protected boolean useAbsoluteFontFileNames() {
return true;
}
/**
* Creates this environment's FontConfiguration.
*/
public abstract FontConfiguration
boolean preferPropFonts);
/**
* Returns face name for default font, or null if
* no face names are used for CompositeFontDescriptors
* for this platform.
*/
if (defaultFontName == null) {
}
return defaultFontName;
}
public void loadFontFiles() {
loadFonts();
if (loadedAllFontFiles) {
return;
}
/* Use lock specific to the font system */
synchronized (this) {
if (FontUtilities.debugFonts()) {
}
}
// this will find all fonts including those already
// registered. But we have checks in place to prevent
// double registration.
registerFontsOnPath(fontPath, false,
false, true);
}
loadedAllFontFiles = true;
return null;
}
});
}
}
/*
* This method asks the font configuration API for all platform names
* looking up their corresponding file name and registers these fonts.
* It also ensures that the fonts are accessible via platform APIs.
* The composites themselves are then registered.
*/
private void
if (FontUtilities.isLogging()) {
.info("Initialising composite fonts");
}
if (fontFileName == null
/* No file located, so register using the platform name,
* i.e. as a native font.
*/
} else {
if (f < numCoreFonts) {
/* If platform APIs also need to access the font, add it
* to a set to be registered with the platform too.
* This may be used to add the parent directory to the X11
* font path if its not already there. See the docs for the
* subclass implementation.
* This is now mainly for the benefit of X11-based AWT
* But for historical reasons, 2D initialisation code
* makes these calls.
* If the fontconfiguration file is properly set up
* so that all fonts are mapped to files and all their
* appropriate directories are specified, then this
* method will be low cost as it will return after
* a test that finds a null lookup map.
*/
}
}
/* Uncomment these two lines to "generate" the XLFD->filename
* mappings needed to speed start-up on Solaris.
* Augment this with the appendedpathname and the mappings
* for native (F3) fonts
*/
//String platName = platformFontName.replaceAll(" ", "_");
//System.out.println("filename."+platName+"="+fontFileName);
Font2D.FONT_CONFIG_RANK, true);
}
/* This registers accumulated paths from the calls to
* addFontToPlatformFontPath(..) and any specified by
* the font configuration. Rather than registering
* the fonts it puts them in a place and form suitable for
* the Toolkit to pick up and use if a toolkit is initialised,
* and if it uses X11 fonts.
*/
/* It would be better eventually to handle this in the
* FontConfiguration code which should also remove duplicate slots
*/
if (missingFontFiles != null) {
}
}
}
/* FontConfiguration needs to convey how many fonts it has added
* as fallback component fonts which should not affect metrics.
* The core component count will be the number of metrics slots.
* This does not preclude other mechanisms for adding
* fall back component fonts to the composite.
*/
if (altNameCache != null) {
true,
} else {
true);
}
if (FontUtilities.debugFonts()) {
}
}
}
/**
* Notifies graphics environment that the logical font configuration
* uses the given platform font name. The graphics environment may
* use this for platform specific initialization.
*/
}
// REMIND: case compare depends on platform
return;
}
int fontFormat;
} else {
}
if (defer) {
fontFormat, false, fontRank);
} else {
fontRank);
}
}
protected void registerPlatformFontsUsedByFontConfiguration() {
}
/*
* A GE may verify whether a font file used in a fontconfiguration
* exists. If it doesn't then either we may substitute the default
* font, or perhaps elide it altogether from the composite font.
* This makes some sense on windows where the font file is only
* likely to be in one place. But on other OSes, eg Linux, the file
* can move around depending. So there we probably don't want to assume
* its missing and so won't add it to this list.
* If this list - missingFontFiles - is non-null then the composite
* font initialisation logic tests to see if a font file is in that
* set.
* Only one thread should be able to add to this set so we don't
* synchronize.
*/
if (missingFontFiles == null) {
}
}
/*
* This is for use only within getAllFonts().
* Fonts listed in the fontconfig files for windows were all
* on the "deferred" initialisation list. They were registered
* either in the course of the application, or in the call to
* loadFonts() within getAllFonts(). The fontconfig file specifies
* the names of the fonts using the English names. If there's a
* different name in the execution locale, then the platform will
* report that, and we will construct the font with both names, and
* thereby enumerate it twice. This happens for Japanese fonts listed
* in the windows fontconfig, when run in the JA locale. The solution
* is to rely (in this case) on the platform's font->file mapping to
* determine that this name corresponds to a file we already registered.
* This works because
* - we know when we get here all deferred fonts are already initialised
* - when we register a font file, we register all fonts in it.
* - we know the fontconfig fonts are all in the windows registry
*/
return false;
}
}
/*
* This invocation is not in a privileged block because
* all privileged operations (reading files and properties)
* was conducted on the creation of the GE
*/
public void
boolean preferLocale,
boolean preferProportional) {
}
/**
* Returns all fonts installed in this environment.
*/
loadFonts();
/* warning: the number of composite fonts could change dynamically
* if applications are allowed to create them. "allfonts" could
* then be stale.
*/
if (!(allfonts[i] instanceof NativeFont)) {
allfonts[i]);
}
}
if (platformNames != null) {
if (!isNameForRegisteredFile(platformNames[i])) {
}
}
}
}
}
}
}
}
return copyFonts;
}
/**
* Get a list of installed fonts in the requested {@link Locale}.
* The list contains the fonts Family Names.
* If Locale is null, the default locale is used.
*
* @param requestedLocale, if null the default locale is used.
* @return list of installed fonts in the system.
*/
if (requestedLocale == null) {
}
return copyFamilies;
}
// these names are always there and aren't localised
/* Platform APIs may be used to get the set of available family
* names for the current default locale so long as it is the same
* as the start-up system locale, rather than loading all fonts.
*/
/* Augment platform names with JRE font family names */
} else {
if (!(physicalfonts[i] instanceof NativeFont)) {
}
}
}
// Add any native font family names here
}
}
return retval;
}
// Provides an aperture to add native font family names to the map
protected void addNativeFontFamilyNames(TreeMap<String, String> familyNames, Locale requestedLocale) { }
public void register1dot0Fonts() {
false, false);
return null;
}
});
}
/* Really we need only the JRE fonts family names, but there's little
* overhead in doing this the easy way by adding all the currently
* known fonts.
*/
if (!(physicalfonts[i] instanceof NativeFont)) {
}
}
}
/**
* Default locale can be changed but we need to know the initial locale
* as that is what is used by native code. Changing Java default locale
* doesn't affect that.
* Returns the locale in use when using native code to communicate
* with platform APIs. On windows this is known as the "system" locale,
* and it is usually the same as the platform locale, but not always,
* so this method also checks an implementation property used only
* on windows and uses that if set.
*/
if (systemLocale == null) {
systemLocale = (Locale)
/* On windows the system locale may be different than the
* user locale. This is an unsupported configuration, but
* in that case we want to return a dummy locale that will
* never cause a match in the usage of this API. This is
* important because Windows documents that the family
* names of fonts are enumerated using the language of
* the system locale. BY returning a dummy locale in that
* case we do not use the platform API which would not
* return us the names we want.
*/
}
}
});
}
return systemLocale;
}
int freeSlot = -1;
synchronized (fontFileCache) {
/* Avoid duplicate entries in the pool, and don't close() it,
* since this method is called only from within open().
* Seeing a duplicate is most likely to happen if the thread
* was interrupted during a read, forcing perhaps repeated
* close and open calls and it eventually it ends up pointing
* at the same slot.
*/
for (int i=0;i<CHANNELPOOLSIZE;i++) {
if (fontFileCache[i] == font) {
return;
}
freeSlot = i;
}
}
if (freeSlot >= 0) {
return;
} else {
/* replace with new font. */
/* lastPoolIndex is updated so that the least recently opened
* file will be closed next.
*/
}
}
/* Need to close the font file outside of the synchronized block,
* since its possible some other thread is in an open() call on
* this font file, and could be holding its lock and the pool lock.
* Releasing the pool lock allows that thread to continue, so it can
* then release the lock on this font, allowing the close() call
* below to proceed.
* Also, calling close() is safe because any other thread using
* the font we are closing() synchronizes all reading, so we
* will not close the file while its in use.
*/
if (fontFileToClose != null) {
}
}
int size)
{
}
}