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