author | pchelko |
Wed, 15 Jan 2014 11:53:54 +0400 | |
changeset 23900 | fd98305f0d19 |
parent 22584 | eed64ee05369 |
child 24520 | e8afd90fcb69 |
permissions | -rw-r--r-- |
12047 | 1 |
/* |
22584
eed64ee05369
8032733: Fix cast lint warnings in client libraries
darcy
parents:
21278
diff
changeset
|
2 |
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. |
12047 | 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 |
package sun.font; |
|
27 |
||
28 |
import java.awt.*; |
|
29 |
import java.io.File; |
|
23900
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
30 |
import java.security.AccessController; |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
31 |
import java.security.PrivilegedAction; |
12047 | 32 |
import java.util.ArrayList; |
33 |
import java.util.HashMap; |
|
34 |
import java.util.Hashtable; |
|
35 |
import java.util.Locale; |
|
36 |
import java.util.TreeMap; |
|
37 |
import java.util.Vector; |
|
38 |
||
39 |
import javax.swing.plaf.FontUIResource; |
|
40 |
||
41 |
import sun.awt.FontConfiguration; |
|
13767
5ea857776c3f
7181199: [macosx] Startup is much slower in headless mode for apps using Fonts
bae
parents:
12047
diff
changeset
|
42 |
import sun.awt.HeadlessToolkit; |
23900
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
43 |
import sun.misc.ThreadGroupUtils; |
12047 | 44 |
import sun.lwawt.macosx.*; |
45 |
||
46 |
public class CFontManager extends SunFontManager { |
|
47 |
private FontConfigManager fcManager = null; |
|
48 |
private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>(); |
|
49 |
||
50 |
@Override |
|
51 |
protected FontConfiguration createFontConfiguration() { |
|
52 |
FontConfiguration fc = new CFontConfiguration(this); |
|
53 |
fc.init(); |
|
54 |
return fc; |
|
55 |
} |
|
56 |
||
57 |
@Override |
|
58 |
public FontConfiguration createFontConfiguration(boolean preferLocaleFonts, |
|
59 |
boolean preferPropFonts) |
|
60 |
{ |
|
61 |
return new CFontConfiguration(this, preferLocaleFonts, preferPropFonts); |
|
62 |
} |
|
63 |
||
64 |
private static String[] defaultPlatformFont = null; |
|
65 |
||
66 |
/* |
|
67 |
* Returns an array of two strings. The first element is the |
|
68 |
* name of the font. The second element is the file name. |
|
69 |
*/ |
|
70 |
@Override |
|
71 |
public synchronized String[] getDefaultPlatformFont() { |
|
72 |
if (defaultPlatformFont == null) { |
|
73 |
defaultPlatformFont = new String[2]; |
|
74 |
defaultPlatformFont[0] = "Lucida Grande"; |
|
75 |
defaultPlatformFont[1] = "/System/Library/Fonts/LucidaGrande.ttc"; |
|
76 |
} |
|
77 |
return defaultPlatformFont; |
|
78 |
} |
|
79 |
||
80 |
// This is a way to register any kind of Font2D, not just files and composites. |
|
81 |
public static Font2D[] getGenericFonts() { |
|
22584
eed64ee05369
8032733: Fix cast lint warnings in client libraries
darcy
parents:
21278
diff
changeset
|
82 |
return genericFonts.values().toArray(new Font2D[0]); |
12047 | 83 |
} |
84 |
||
85 |
public Font2D registerGenericFont(Font2D f) |
|
86 |
{ |
|
87 |
return registerGenericFont(f, false); |
|
88 |
} |
|
89 |
public Font2D registerGenericFont(Font2D f, boolean logicalFont) |
|
90 |
{ |
|
91 |
int rank = 4; |
|
92 |
||
93 |
String fontName = f.fullName; |
|
94 |
String familyName = f.familyName; |
|
95 |
||
96 |
if (fontName == null || "".equals(fontName)) { |
|
97 |
return null; |
|
98 |
} |
|
99 |
||
100 |
// logical fonts always need to be added to the family |
|
101 |
// plus they never need to be added to the generic font list |
|
102 |
// or the fullNameToFont table since they are covers for |
|
103 |
// already existing fonts in this list |
|
104 |
if (logicalFont || !genericFonts.containsKey(fontName)) { |
|
105 |
if (FontUtilities.debugFonts()) { |
|
106 |
FontUtilities.getLogger().info("Add to Family "+familyName + |
|
107 |
", Font " + fontName + " rank="+rank); |
|
108 |
} |
|
109 |
FontFamily family = FontFamily.getFamily(familyName); |
|
110 |
if (family == null) { |
|
111 |
family = new FontFamily(familyName, false, rank); |
|
112 |
family.setFont(f, f.style); |
|
113 |
} else if (family.getRank() >= rank) { |
|
114 |
family.setFont(f, f.style); |
|
115 |
} |
|
116 |
if (!logicalFont) |
|
117 |
{ |
|
118 |
genericFonts.put(fontName, f); |
|
119 |
fullNameToFont.put(fontName.toLowerCase(Locale.ENGLISH), f); |
|
120 |
} |
|
121 |
return f; |
|
122 |
} else { |
|
22584
eed64ee05369
8032733: Fix cast lint warnings in client libraries
darcy
parents:
21278
diff
changeset
|
123 |
return genericFonts.get(fontName); |
12047 | 124 |
} |
125 |
} |
|
126 |
||
127 |
@Override |
|
128 |
public Font2D[] getRegisteredFonts() { |
|
129 |
Font2D[] regFonts = super.getRegisteredFonts(); |
|
130 |
||
131 |
// Add in the Mac OS X native fonts |
|
132 |
Font2D[] genericFonts = getGenericFonts(); |
|
133 |
Font2D[] allFonts = new Font2D[regFonts.length+genericFonts.length]; |
|
134 |
System.arraycopy(regFonts, 0, allFonts, 0, regFonts.length); |
|
135 |
System.arraycopy(genericFonts, 0, allFonts, regFonts.length, genericFonts.length); |
|
136 |
||
137 |
return allFonts; |
|
138 |
} |
|
139 |
||
140 |
@Override |
|
141 |
protected void addNativeFontFamilyNames(TreeMap<String, String> familyNames, Locale requestedLocale) { |
|
142 |
Font2D[] genericfonts = getGenericFonts(); |
|
143 |
for (int i=0; i < genericfonts.length; i++) { |
|
144 |
if (!(genericfonts[i] instanceof NativeFont)) { |
|
145 |
String name = genericfonts[i].getFamilyName(requestedLocale); |
|
146 |
familyNames.put(name.toLowerCase(requestedLocale), name); |
|
147 |
} |
|
148 |
} |
|
149 |
} |
|
150 |
||
151 |
@Override |
|
152 |
public Font2D createFont2D(File fontFile, int fontFormat, boolean isCopy, CreatedFontTracker tracker) throws FontFormatException { |
|
153 |
||
154 |
String fontFilePath = fontFile.getPath(); |
|
155 |
Font2D font2D = null; |
|
156 |
final File fFile = fontFile; |
|
157 |
final CreatedFontTracker _tracker = tracker; |
|
158 |
try { |
|
159 |
switch (fontFormat) { |
|
160 |
case Font.TRUETYPE_FONT: |
|
161 |
font2D = new TrueTypeFont(fontFilePath, null, 0, true); |
|
162 |
break; |
|
163 |
case Font.TYPE1_FONT: |
|
164 |
font2D = new Type1Font(fontFilePath, null, isCopy); |
|
165 |
break; |
|
166 |
default: |
|
167 |
throw new FontFormatException("Unrecognised Font Format"); |
|
168 |
} |
|
169 |
} catch (FontFormatException e) { |
|
170 |
if (isCopy) { |
|
171 |
java.security.AccessController.doPrivileged( |
|
172 |
new java.security.PrivilegedAction<Object>() { |
|
173 |
public Object run() { |
|
174 |
if (_tracker != null) { |
|
175 |
_tracker.subBytes((int)fFile.length()); |
|
176 |
} |
|
177 |
fFile.delete(); |
|
178 |
return null; |
|
179 |
} |
|
180 |
}); |
|
181 |
} |
|
182 |
throw(e); |
|
183 |
} |
|
184 |
if (isCopy) { |
|
185 |
FileFont.setFileToRemove(font2D, fontFile, tracker); |
|
186 |
synchronized (FontManager.class) { |
|
187 |
||
188 |
if (tmpFontFiles == null) { |
|
189 |
tmpFontFiles = new Vector<File>(); |
|
190 |
} |
|
191 |
tmpFontFiles.add(fontFile); |
|
192 |
||
193 |
if (fileCloser == null) { |
|
194 |
final Runnable fileCloserRunnable = new Runnable() { |
|
195 |
public void run() { |
|
196 |
java.security.AccessController.doPrivileged( |
|
197 |
new java.security.PrivilegedAction<Object>() { |
|
198 |
public Object run() { |
|
199 |
||
200 |
for (int i=0;i<CHANNELPOOLSIZE;i++) { |
|
201 |
if (fontFileCache[i] != null) { |
|
202 |
try { |
|
203 |
fontFileCache[i].close(); |
|
204 |
} catch (Exception e) {} |
|
205 |
} |
|
206 |
} |
|
207 |
if (tmpFontFiles != null) { |
|
208 |
File[] files = new File[tmpFontFiles.size()]; |
|
209 |
files = tmpFontFiles.toArray(files); |
|
210 |
for (int f=0; f<files.length;f++) { |
|
211 |
try { |
|
212 |
files[f].delete(); |
|
213 |
} catch (Exception e) {} |
|
214 |
} |
|
215 |
} |
|
216 |
return null; |
|
217 |
} |
|
218 |
}); |
|
219 |
} |
|
220 |
}; |
|
23900
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
221 |
AccessController.doPrivileged( |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
222 |
(PrivilegedAction<Void>) () -> { |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
223 |
/* The thread must be a member of a thread group |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
224 |
* which will not get GCed before VM exit. |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
225 |
* Make its parent the top-level thread group. |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
226 |
*/ |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
227 |
ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
228 |
fileCloser = new Thread(rootTG, fileCloserRunnable); |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
229 |
fileCloser.setContextClassLoader(null); |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
230 |
Runtime.getRuntime().addShutdownHook(fileCloser); |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
231 |
return null; |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
232 |
} |
fd98305f0d19
8031477: [macosx] Loading AWT native library fails
pchelko
parents:
22584
diff
changeset
|
233 |
); |
12047 | 234 |
} |
235 |
} |
|
236 |
} |
|
237 |
return font2D; |
|
238 |
} |
|
239 |
||
240 |
/* |
|
241 |
public synchronized FontConfigManager getFontConfigManager() { |
|
242 |
if (fcManager == null) { |
|
243 |
fcManager = new FontConfigManager(); |
|
244 |
} |
|
245 |
return fcManager; |
|
246 |
} |
|
247 |
*/ |
|
248 |
||
249 |
protected void registerFontsInDir(String dirName, boolean useJavaRasterizer, int fontRank, boolean defer, boolean resolveSymLinks) { |
|
250 |
loadNativeDirFonts(dirName); |
|
251 |
super.registerFontsInDir(dirName, useJavaRasterizer, fontRank, defer, resolveSymLinks); |
|
252 |
} |
|
253 |
||
254 |
private native void loadNativeDirFonts(String dirName); |
|
255 |
private native void loadNativeFonts(); |
|
256 |
||
257 |
void registerFont(String fontName, String fontFamilyName) { |
|
258 |
final CFont font = new CFont(fontName, fontFamilyName); |
|
259 |
||
260 |
registerGenericFont(font); |
|
261 |
||
262 |
if ((font.getStyle() & Font.ITALIC) == 0) { |
|
263 |
registerGenericFont(font.createItalicVariant(), true); |
|
264 |
} |
|
265 |
} |
|
266 |
||
267 |
Object waitForFontsToBeLoaded = new Object(); |
|
268 |
public void loadFonts() |
|
269 |
{ |
|
270 |
synchronized(waitForFontsToBeLoaded) |
|
271 |
{ |
|
272 |
super.loadFonts(); |
|
273 |
java.security.AccessController.doPrivileged( |
|
274 |
new java.security.PrivilegedAction<Object>() { |
|
275 |
public Object run() { |
|
276 |
loadNativeFonts(); |
|
277 |
return null; |
|
278 |
} |
|
279 |
} |
|
280 |
); |
|
281 |
||
282 |
String defaultFont = "Lucida Grande"; |
|
283 |
String defaultFallback = "Lucida Sans"; |
|
284 |
||
285 |
setupLogicalFonts("Dialog", defaultFont, defaultFallback); |
|
286 |
setupLogicalFonts("Serif", "Times", "Lucida Bright"); |
|
287 |
setupLogicalFonts("SansSerif", defaultFont, defaultFallback); |
|
288 |
setupLogicalFonts("Monospaced", "Menlo", "Lucida Sans Typewriter"); |
|
289 |
setupLogicalFonts("DialogInput", defaultFont, defaultFallback); |
|
290 |
} |
|
291 |
} |
|
292 |
||
293 |
protected void setupLogicalFonts(String logicalName, String realName, String fallbackName) { |
|
294 |
FontFamily realFamily = getFontFamilyWithExtraTry(logicalName, realName, fallbackName); |
|
295 |
||
296 |
cloneStyledFont(realFamily, logicalName, Font.PLAIN); |
|
297 |
cloneStyledFont(realFamily, logicalName, Font.BOLD); |
|
298 |
cloneStyledFont(realFamily, logicalName, Font.ITALIC); |
|
299 |
cloneStyledFont(realFamily, logicalName, Font.BOLD | Font.ITALIC); |
|
300 |
} |
|
301 |
||
302 |
protected FontFamily getFontFamilyWithExtraTry(String logicalName, String realName, String fallbackName){ |
|
303 |
FontFamily family = getFontFamily(realName, fallbackName); |
|
304 |
if (family != null) return family; |
|
305 |
||
306 |
// at this point, we recognize that we probably needed a fallback font |
|
307 |
super.loadFonts(); |
|
308 |
||
309 |
family = getFontFamily(realName, fallbackName); |
|
310 |
if (family != null) return family; |
|
311 |
||
312 |
System.err.println("Warning: the fonts \"" + realName + "\" and \"" + fallbackName + "\" are not available for the Java logical font \"" + logicalName + "\", which may have unexpected appearance or behavior. Re-enable the \""+ realName +"\" font to remove this warning."); |
|
313 |
return null; |
|
314 |
} |
|
315 |
||
316 |
protected FontFamily getFontFamily(String realName, String fallbackName){ |
|
317 |
FontFamily family = FontFamily.getFamily(realName); |
|
318 |
if (family != null) return family; |
|
319 |
||
320 |
family = FontFamily.getFamily(fallbackName); |
|
321 |
if (family != null){ |
|
322 |
System.err.println("Warning: the font \"" + realName + "\" is not available, so \"" + fallbackName + "\" has been substituted, but may have unexpected appearance or behavor. Re-enable the \""+ realName +"\" font to remove this warning."); |
|
323 |
return family; |
|
324 |
} |
|
325 |
||
326 |
return null; |
|
327 |
} |
|
328 |
||
329 |
protected boolean cloneStyledFont(FontFamily realFamily, String logicalFamilyName, int style) { |
|
330 |
if (realFamily == null) return false; |
|
331 |
||
332 |
Font2D realFont = realFamily.getFontWithExactStyleMatch(style); |
|
333 |
if (realFont == null || !(realFont instanceof CFont)) return false; |
|
334 |
||
335 |
CFont newFont = new CFont((CFont)realFont, logicalFamilyName); |
|
336 |
registerGenericFont(newFont, true); |
|
337 |
||
338 |
return true; |
|
339 |
} |
|
340 |
||
341 |
@Override |
|
342 |
public String getFontPath(boolean noType1Fonts) { |
|
21278 | 343 |
// In the case of the Cocoa toolkit, since we go through NSFont, we don't need to register /Library/Fonts |
13767
5ea857776c3f
7181199: [macosx] Startup is much slower in headless mode for apps using Fonts
bae
parents:
12047
diff
changeset
|
344 |
Toolkit tk = Toolkit.getDefaultToolkit(); |
5ea857776c3f
7181199: [macosx] Startup is much slower in headless mode for apps using Fonts
bae
parents:
12047
diff
changeset
|
345 |
if (tk instanceof HeadlessToolkit) { |
5ea857776c3f
7181199: [macosx] Startup is much slower in headless mode for apps using Fonts
bae
parents:
12047
diff
changeset
|
346 |
tk = ((HeadlessToolkit)tk).getUnderlyingToolkit(); |
5ea857776c3f
7181199: [macosx] Startup is much slower in headless mode for apps using Fonts
bae
parents:
12047
diff
changeset
|
347 |
} |
5ea857776c3f
7181199: [macosx] Startup is much slower in headless mode for apps using Fonts
bae
parents:
12047
diff
changeset
|
348 |
if (tk instanceof LWCToolkit) { |
12047 | 349 |
return ""; |
350 |
} |
|
13767
5ea857776c3f
7181199: [macosx] Startup is much slower in headless mode for apps using Fonts
bae
parents:
12047
diff
changeset
|
351 |
|
12047 | 352 |
// X11 case |
353 |
return "/Library/Fonts"; |
|
354 |
} |
|
355 |
||
356 |
@Override |
|
357 |
protected FontUIResource getFontConfigFUIR( |
|
358 |
String family, int style, int size) |
|
359 |
{ |
|
360 |
String mappedName = FontUtilities.mapFcName(family); |
|
361 |
if (mappedName == null) { |
|
362 |
mappedName = "sansserif"; |
|
363 |
} |
|
364 |
return new FontUIResource(mappedName, style, size); |
|
365 |
} |
|
366 |
||
367 |
// Only implemented on Windows |
|
368 |
@Override |
|
369 |
protected void populateFontFileNameMap(HashMap<String, String> fontToFileMap, HashMap<String, String> fontToFamilyNameMap, |
|
370 |
HashMap<String, ArrayList<String>> familyToFontListMap, Locale locale) {} |
|
371 |
} |