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