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