1 /*
   2  * Copyright 2008 Sun Microsystems, Inc.  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.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any 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                                                         true);
  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 Win32FontManager() {
  85         super();
  86         AccessController.doPrivileged(new PrivilegedAction() {
  87                 public Object run() {
  88 
  89                     /* Register the JRE fonts so that the native platform can
  90                      * access them. This is used only on Windows so that when
  91                      * printing the printer driver can access the fonts.
  92                      */
  93                     registerJREFontsWithPlatform(jreFontDirName);
  94                     return null;
  95                 }
  96             });
  97     }
  98 
  99     /* Unlike the shared code version, this expects a base file name -
 100      * not a full path name.
 101      * The font configuration file has base file names and the FontConfiguration
 102      * class reports these back to the GraphicsEnvironment, so these
 103      * are the componentFileNames of CompositeFonts.
 104      */
 105     protected void registerFontFile(String fontFileName, String[] nativeNames,
 106                                     int fontRank, boolean defer) {
 107 
 108         // REMIND: case compare depends on platform
 109         if (registeredFontFiles.contains(fontFileName)) {
 110             return;
 111         }
 112         registeredFontFiles.add(fontFileName);
 113 
 114         int fontFormat;
 115         if (getTrueTypeFilter().accept(null, fontFileName)) {
 116             fontFormat = SunFontManager.FONTFORMAT_TRUETYPE;
 117         } else if (getType1Filter().accept(null, fontFileName)) {
 118             fontFormat = SunFontManager.FONTFORMAT_TYPE1;
 119         } else {
 120             /* on windows we don't use/register native fonts */
 121             return;
 122         }
 123 
 124         if (fontPath == null) {
 125             fontPath = getPlatformFontPath(noType1Font);
 126         }
 127 
 128         /* Look in the JRE font directory first.
 129          * This is playing it safe as we would want to find fonts in the
 130          * JRE font directory ahead of those in the system directory
 131          */
 132         String tmpFontPath = jreFontDirName+File.pathSeparator+fontPath;
 133         StringTokenizer parser = new StringTokenizer(tmpFontPath,
 134                                                      File.pathSeparator);
 135 
 136         boolean found = false;
 137         try {
 138             while (!found && parser.hasMoreTokens()) {
 139                 String newPath = parser.nextToken();
 140                 File theFile = new File(newPath, fontFileName);
 141                 if (theFile.canRead()) {
 142                     found = true;
 143                     String path = theFile.getAbsolutePath();
 144                     if (defer) {
 145                         registerDeferredFont(fontFileName, path,
 146                                              nativeNames,
 147                                              fontFormat, true,
 148                                              fontRank);
 149                     } else {
 150                         registerFontFile(path, nativeNames,
 151                                          fontFormat, true,
 152                                          fontRank);
 153                     }
 154                     break;
 155                 }
 156             }
 157         } catch (NoSuchElementException e) {
 158             System.err.println(e);
 159         }
 160         if (!found) {
 161             addToMissingFontFileList(fontFileName);
 162         }
 163     }
 164 
 165     @Override
 166     protected FontConfiguration createFontConfiguration() {
 167         
 168        FontConfiguration fc = new WFontConfiguration(this);
 169        fc.init();
 170        return fc;
 171     }
 172 
 173     @Override
 174     public FontConfiguration createFontConfiguration(boolean preferLocaleFonts,
 175             boolean preferPropFonts) {
 176         
 177         return new WFontConfiguration(this,
 178                                       preferLocaleFonts,preferPropFonts);
 179     }
 180 
 181     protected void
 182         populateFontFileNameMap(HashMap<String,String> fontToFileMap,
 183                                 HashMap<String,String> fontToFamilyNameMap,
 184                                 HashMap<String,ArrayList<String>>
 185                                 familyToFontListMap,
 186                                 Locale locale) {
 187 
 188         populateFontFileNameMap0(fontToFileMap, fontToFamilyNameMap,
 189                                  familyToFontListMap, locale);
 190 
 191     }
 192 
 193     private static native void
 194         populateFontFileNameMap0(HashMap<String,String> fontToFileMap,
 195                                  HashMap<String,String> fontToFamilyNameMap,
 196                                  HashMap<String,ArrayList<String>>
 197                                      familyToFontListMap,
 198                                  Locale locale);
 199 
 200     public synchronized native String getFontPath(boolean noType1Fonts);
 201 
 202     public String[] getDefaultPlatformFont() {
 203 
 204         if (defaultPlatformFont != null) {
 205             return defaultPlatformFont;
 206         }
 207 
 208         String[] info = new String[2];
 209         info[0] = "Arial";
 210         info[1] = "c:\\windows\\fonts";
 211         final String[] dirs = getPlatformFontDirs(true);
 212         if (dirs.length > 1) {
 213             String dir = (String)
 214                 AccessController.doPrivileged(new PrivilegedAction() {
 215                         public Object run() {
 216                             for (int i=0; i<dirs.length; i++) {
 217                                 String path =
 218                                     dirs[i] + File.separator + "arial.ttf";
 219                                 File file = new File(path);
 220                                 if (file.exists()) {
 221                                     return dirs[i];
 222                                 }
 223                             }
 224                             return null;
 225                         }
 226                     });
 227             if (dir != null) {
 228                 info[1] = dir;
 229             }
 230         } else {
 231             info[1] = dirs[0];
 232         }
 233         info[1] = info[1] + File.separator + "arial.ttf";
 234         defaultPlatformFont = info;
 235         return defaultPlatformFont;
 236     }
 237 
 238     /* register only TrueType/OpenType fonts
 239      * Because these need to be registed just for use when printing,
 240      * we defer the actual registration and the static initialiser
 241      * for the printing class makes the call to registerJREFontsForPrinting()
 242      */
 243     static String fontsForPrinting = null;
 244     protected void registerJREFontsWithPlatform(String pathName) {
 245         fontsForPrinting = pathName;
 246     }
 247 
 248     public static void registerJREFontsForPrinting() {
 249         final String pathName;
 250         synchronized (Win32GraphicsEnvironment.class) {
 251             GraphicsEnvironment.getLocalGraphicsEnvironment();
 252             if (fontsForPrinting == null) {
 253                 return;
 254             }
 255             pathName = fontsForPrinting;
 256             fontsForPrinting = null;
 257         }
 258         java.security.AccessController.doPrivileged(
 259             new java.security.PrivilegedAction() {
 260                 public Object run() {
 261                     File f1 = new File(pathName);
 262                     String[] ls = f1.list(SunFontManager.getInstance().
 263                             getTrueTypeFilter());
 264                     if (ls == null) {
 265                         return null;
 266                     }
 267                     for (int i=0; i <ls.length; i++ ) {
 268                         File fontFile = new File(f1, ls[i]);
 269                         registerFontWithPlatform(fontFile.getAbsolutePath());
 270                     }
 271                     return null;
 272                 }
 273          });
 274     }
 275 
 276     protected static native void registerFontWithPlatform(String fontName);
 277 
 278     protected static native void deRegisterFontWithPlatform(String fontName);
 279 
 280 }