1 /* 2 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27 package sun.awt; 28 29 import java.awt.FontFormatException; 30 import java.awt.GraphicsEnvironment; 31 import java.io.File; 32 import java.security.AccessController; 33 import java.security.PrivilegedAction; 34 import java.util.ArrayList; 35 import java.util.HashMap; 36 import java.util.Locale; 37 import java.util.NoSuchElementException; 38 import java.util.StringTokenizer; 39 40 import sun.awt.Win32GraphicsEnvironment; 41 import sun.awt.windows.WFontConfiguration; 42 import sun.font.FontManager; 43 import sun.font.SunFontManager; 44 import sun.font.TrueTypeFont; 45 import sun.java2d.HeadlessGraphicsEnvironment; 46 import sun.java2d.SunGraphicsEnvironment; 47 48 /** 49 * The X11 implementation of {@link FontManager}. 50 */ 51 public class Win32FontManager extends SunFontManager { 52 53 private static String[] defaultPlatformFont = null; 54 55 private static TrueTypeFont eudcFont; 56 57 static { 58 59 AccessController.doPrivileged(new PrivilegedAction() { 60 61 public Object run() { 62 String eudcFile = getEUDCFontFile(); 63 if (eudcFile != null) { 64 try { 65 eudcFont = new TrueTypeFont(eudcFile, null, 0, 66 false); 67 } catch (FontFormatException e) { 68 } 69 } 70 return null; 71 } 72 73 }); 74 } 75 76 /* Used on Windows to obtain from the windows registry the name 77 * of a file containing the system EUFC font. If running in one of 78 * the locales for which this applies, and one is defined, the font 79 * defined by this file is appended to all composite fonts as a 80 * fallback component. 81 */ 82 private static native String getEUDCFontFile(); 83 84 public TrueTypeFont getEUDCFont() { 85 return eudcFont; 86 } 87 88 public Win32FontManager() { 89 super(); 90 AccessController.doPrivileged(new PrivilegedAction() { 91 public Object run() { 92 93 /* Register the JRE fonts so that the native platform can 94 * access them. This is used only on Windows so that when 95 * printing the printer driver can access the fonts. 96 */ 97 registerJREFontsWithPlatform(jreFontDirName); 98 return null; 99 } 100 }); 101 } 102 103 /* Unlike the shared code version, this expects a base file name - 104 * not a full path name. 105 * The font configuration file has base file names and the FontConfiguration 106 * class reports these back to the GraphicsEnvironment, so these 107 * are the componentFileNames of CompositeFonts. 108 */ 109 protected void registerFontFile(String fontFileName, String[] nativeNames, 110 int fontRank, boolean defer) { 111 112 // REMIND: case compare depends on platform 113 if (registeredFontFiles.contains(fontFileName)) { 114 return; 115 } 116 registeredFontFiles.add(fontFileName); 117 118 int fontFormat; 119 if (getTrueTypeFilter().accept(null, fontFileName)) { 120 fontFormat = SunFontManager.FONTFORMAT_TRUETYPE; 121 } else if (getType1Filter().accept(null, fontFileName)) { 122 fontFormat = SunFontManager.FONTFORMAT_TYPE1; 123 } else { 124 /* on windows we don't use/register native fonts */ 125 return; 126 } 127 128 if (fontPath == null) { 129 fontPath = getPlatformFontPath(noType1Font); 130 } 131 132 /* Look in the JRE font directory first. 133 * This is playing it safe as we would want to find fonts in the 134 * JRE font directory ahead of those in the system directory 135 */ 136 String tmpFontPath = jreFontDirName+File.pathSeparator+fontPath; 137 StringTokenizer parser = new StringTokenizer(tmpFontPath, 138 File.pathSeparator); 139 140 boolean found = false; 141 try { 142 while (!found && parser.hasMoreTokens()) { 143 String newPath = parser.nextToken(); 144 boolean isJREFont = newPath.equals(jreFontDirName); 145 File theFile = new File(newPath, fontFileName); 146 if (theFile.canRead()) { 147 found = true; 148 String path = theFile.getAbsolutePath(); 149 if (defer) { 150 registerDeferredFont(fontFileName, path, 151 nativeNames, 152 fontFormat, isJREFont, 153 fontRank); 154 } else { 155 registerFontFile(path, nativeNames, 156 fontFormat, isJREFont, 157 fontRank); 158 } 159 break; 160 } 161 } 162 } catch (NoSuchElementException e) { 163 System.err.println(e); 164 } 165 if (!found) { 166 addToMissingFontFileList(fontFileName); 167 } 168 } 169 170 @Override 171 protected FontConfiguration createFontConfiguration() { 172 173 FontConfiguration fc = new WFontConfiguration(this); 174 fc.init(); 175 return fc; 176 } 177 178 @Override 179 public FontConfiguration createFontConfiguration(boolean preferLocaleFonts, 180 boolean preferPropFonts) { 181 182 return new WFontConfiguration(this, 183 preferLocaleFonts,preferPropFonts); 184 } 185 186 protected void 187 populateFontFileNameMap(HashMap<String,String> fontToFileMap, 188 HashMap<String,String> fontToFamilyNameMap, 189 HashMap<String,ArrayList<String>> 190 familyToFontListMap, 191 Locale locale) { 192 193 populateFontFileNameMap0(fontToFileMap, fontToFamilyNameMap, 194 familyToFontListMap, locale); 195 196 } 197 198 private static native void 199 populateFontFileNameMap0(HashMap<String,String> fontToFileMap, 200 HashMap<String,String> fontToFamilyNameMap, 201 HashMap<String,ArrayList<String>> 202 familyToFontListMap, 203 Locale locale); 204 205 protected synchronized native String getFontPath(boolean noType1Fonts); 206 207 public String[] getDefaultPlatformFont() { 208 209 if (defaultPlatformFont != null) { 210 return defaultPlatformFont; 211 } 212 213 String[] info = new String[2]; 214 info[0] = "Arial"; 215 info[1] = "c:\\windows\\fonts"; 216 final String[] dirs = getPlatformFontDirs(true); 217 if (dirs.length > 1) { 218 String dir = (String) 219 AccessController.doPrivileged(new PrivilegedAction() { 220 public Object run() { 221 for (int i=0; i<dirs.length; i++) { 222 String path = 223 dirs[i] + File.separator + "arial.ttf"; 224 File file = new File(path); 225 if (file.exists()) { 226 return dirs[i]; 227 } 228 } 229 return null; 230 } 231 }); 232 if (dir != null) { 233 info[1] = dir; 234 } 235 } else { 236 info[1] = dirs[0]; 237 } 238 info[1] = info[1] + File.separator + "arial.ttf"; 239 defaultPlatformFont = info; 240 return defaultPlatformFont; 241 } 242 243 /* register only TrueType/OpenType fonts 244 * Because these need to be registed just for use when printing, 245 * we defer the actual registration and the static initialiser 246 * for the printing class makes the call to registerJREFontsForPrinting() 247 */ 248 static String fontsForPrinting = null; 249 protected void registerJREFontsWithPlatform(String pathName) { 250 fontsForPrinting = pathName; 251 } 252 253 public static void registerJREFontsForPrinting() { 254 final String pathName; 255 synchronized (Win32GraphicsEnvironment.class) { 256 GraphicsEnvironment.getLocalGraphicsEnvironment(); 257 if (fontsForPrinting == null) { 258 return; 259 } 260 pathName = fontsForPrinting; 261 fontsForPrinting = null; 262 } 263 java.security.AccessController.doPrivileged( 264 new java.security.PrivilegedAction() { 265 public Object run() { 266 File f1 = new File(pathName); 267 String[] ls = f1.list(SunFontManager.getInstance(). 268 getTrueTypeFilter()); 269 if (ls == null) { 270 return null; 271 } 272 for (int i=0; i <ls.length; i++ ) { 273 File fontFile = new File(f1, ls[i]); 274 registerFontWithPlatform(fontFile.getAbsolutePath()); 275 } 276 return null; 277 } 278 }); 279 } 280 281 protected static native void registerFontWithPlatform(String fontName); 282 283 protected static native void deRegisterFontWithPlatform(String fontName); 284 285 /** 286 * populate the map with the most common windows fonts. 287 */ 288 @Override 289 public HashMap<String, FamilyDescription> populateHardcodedFileNameMap() { 290 HashMap<String, FamilyDescription> platformFontMap 291 = new HashMap<String, FamilyDescription>(); 292 FamilyDescription fd; 293 294 /* Segoe UI is the default UI font for Vista and later, and 295 * is used by the Win L&F which is used by FX too. 296 * Tahoma is used for the Win L&F on XP. 297 * Verdana is used in some FX UI controls. 298 */ 299 fd = new FamilyDescription(); 300 fd.familyName = "Segoe UI"; 301 fd.plainFullName = "Segoe UI"; 302 fd.plainFileName = "segoeui.ttf"; 303 fd.boldFullName = "Segoe UI Bold"; 304 fd.boldFileName = "segoeuib.ttf"; 305 fd.italicFullName = "Segoe UI Italic"; 306 fd.italicFileName = "segoeuii.ttf"; 307 fd.boldItalicFullName = "Segoe UI Bold Italic"; 308 fd.boldItalicFileName = "segoeuiz.ttf"; 309 platformFontMap.put("segoe", fd); 310 311 fd = new FamilyDescription(); 312 fd.familyName = "Tahoma"; 313 fd.plainFullName = "Tahoma"; 314 fd.plainFileName = "tahoma.ttf"; 315 fd.boldFullName = "Tahoma Bold"; 316 fd.boldFileName = "tahomabd.ttf"; 317 platformFontMap.put("tahoma", fd); 318 319 fd = new FamilyDescription(); 320 fd.familyName = "Verdana"; 321 fd.plainFullName = "Verdana"; 322 fd.plainFileName = "verdana.TTF"; 323 fd.boldFullName = "Verdana Bold"; 324 fd.boldFileName = "verdanab.TTF"; 325 fd.italicFullName = "Verdana Italic"; 326 fd.italicFileName = "verdanai.TTF"; 327 fd.boldItalicFullName = "Verdana Bold Italic"; 328 fd.boldItalicFileName = "verdanaz.TTF"; 329 platformFontMap.put("verdana", fd); 330 331 /* The following are important because they are the core 332 * members of the default "Dialog" font. 333 */ 334 fd = new FamilyDescription(); 335 fd.familyName = "Arial"; 336 fd.plainFullName = "Arial"; 337 fd.plainFileName = "ARIAL.TTF"; 338 fd.boldFullName = "Arial Bold"; 339 fd.boldFileName = "ARIALBD.TTF"; 340 fd.italicFullName = "Arial Italic"; 341 fd.italicFileName = "ARIALI.TTF"; 342 fd.boldItalicFullName = "Arial Bold Italic"; 343 fd.boldItalicFileName = "ARIALBI.TTF"; 344 platformFontMap.put("arial", fd); 345 346 fd = new FamilyDescription(); 347 fd.familyName = "Symbol"; 348 fd.plainFullName = "Symbol"; 349 fd.plainFileName = "Symbol.TTF"; 350 platformFontMap.put("symbol", fd); 351 352 fd = new FamilyDescription(); 353 fd.familyName = "WingDings"; 354 fd.plainFullName = "WingDings"; 355 fd.plainFileName = "WINGDING.TTF"; 356 platformFontMap.put("wingdings", fd); 357 358 return platformFontMap; 359 } 360 }