1 /* 2 * Copyright (c) 2001, 2020, 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 package sun.awt.windows; 27 28 import java.util.HashMap; 29 import java.util.Hashtable; 30 import sun.awt.FontDescriptor; 31 import sun.awt.FontConfiguration; 32 import sun.font.SunFontManager; 33 import java.nio.charset.*; 34 35 public final class WFontConfiguration extends FontConfiguration { 36 37 // whether compatibility fallbacks for TimesRoman and Co. are used 38 private boolean useCompatibilityFallbacks; 39 WFontConfiguration(SunFontManager fm)40 public WFontConfiguration(SunFontManager fm) { 41 super(fm); 42 useCompatibilityFallbacks = "windows-1252".equals(encoding); 43 initTables(encoding); 44 } 45 WFontConfiguration(SunFontManager fm, boolean preferLocaleFonts, boolean preferPropFonts)46 public WFontConfiguration(SunFontManager fm, 47 boolean preferLocaleFonts, 48 boolean preferPropFonts) { 49 super(fm, preferLocaleFonts, preferPropFonts); 50 useCompatibilityFallbacks = "windows-1252".equals(encoding); 51 } 52 53 @Override initReorderMap()54 protected void initReorderMap() { 55 if (encoding.equalsIgnoreCase("windows-31j")) { 56 localeMap = new Hashtable<>(); 57 /* Substitute Mincho for Gothic in this one case. 58 * Note the windows fontconfig files already contain the mapping: 59 * filename.MS_Mincho=MSMINCHO.TTC 60 * which isn't essential to this usage but avoids a call 61 * to loadfonts in the event MSMINCHO.TTC has not otherwise 62 * been opened and its fonts loaded. 63 * Also note this usage is only enabled if a private flag is set. 64 */ 65 localeMap.put("dialoginput.plain.japanese", "MS Mincho"); 66 localeMap.put("dialoginput.bold.japanese", "MS Mincho"); 67 localeMap.put("dialoginput.italic.japanese", "MS Mincho"); 68 localeMap.put("dialoginput.bolditalic.japanese", "MS Mincho"); 69 } 70 reorderMap = new HashMap<>(); 71 reorderMap.put("UTF-8.hi", "devanagari"); 72 reorderMap.put("windows-1255", "hebrew"); 73 reorderMap.put("x-windows-874", "thai"); 74 reorderMap.put("windows-31j", "japanese"); 75 reorderMap.put("x-windows-949", "korean"); 76 reorderMap.put("GBK", "chinese-ms936"); 77 reorderMap.put("GB18030", "chinese-gb18030"); 78 reorderMap.put("x-windows-950", "chinese-ms950"); 79 reorderMap.put("x-MS950-HKSCS", split("chinese-ms950,chinese-hkscs")); 80 // reorderMap.put("windows-1252", "alphabetic"); 81 } 82 83 @Override setOsNameAndVersion()84 protected void setOsNameAndVersion(){ 85 super.setOsNameAndVersion(); 86 if (osName.startsWith("Windows")){ 87 int p, q; 88 p = osName.indexOf(' '); 89 if (p == -1){ 90 osName = null; 91 } 92 else{ 93 q = osName.indexOf(' ', p + 1); 94 if (q == -1){ 95 osName = osName.substring(p + 1); 96 } 97 else{ 98 osName = osName.substring(p + 1, q); 99 } 100 } 101 osVersion = null; 102 } 103 } 104 105 // overrides FontConfiguration.getFallbackFamilyName 106 @Override getFallbackFamilyName(String fontName, String defaultFallback)107 public String getFallbackFamilyName(String fontName, String defaultFallback) { 108 // maintain compatibility with old font.properties files, where 109 // default file had aliases for timesroman & Co, while others didn't. 110 if (useCompatibilityFallbacks) { 111 String compatibilityName = getCompatibilityFamilyName(fontName); 112 if (compatibilityName != null) { 113 return compatibilityName; 114 } 115 } 116 return defaultFallback; 117 } 118 119 @Override makeAWTFontName(String platformFontName, String characterSubsetName)120 protected String makeAWTFontName(String platformFontName, String characterSubsetName) { 121 String windowsCharset = subsetCharsetMap.get(characterSubsetName); 122 if (windowsCharset == null) { 123 windowsCharset = "DEFAULT_CHARSET"; 124 } 125 return platformFontName + "," + windowsCharset; 126 } 127 128 @Override getEncoding(String awtFontName, String characterSubsetName)129 protected String getEncoding(String awtFontName, String characterSubsetName) { 130 String encoding = subsetEncodingMap.get(characterSubsetName); 131 if (encoding == null) { 132 encoding = "default"; 133 } 134 return encoding; 135 } 136 137 @Override getDefaultFontCharset(String fontName)138 protected Charset getDefaultFontCharset(String fontName) { 139 return new WDefaultFontCharset(fontName); 140 } 141 142 @Override getFaceNameFromComponentFontName(String componentFontName)143 public String getFaceNameFromComponentFontName(String componentFontName) { 144 // for Windows, the platform name is the face name 145 return componentFontName; 146 } 147 148 @Override getFileNameFromComponentFontName(String componentFontName)149 protected String getFileNameFromComponentFontName(String componentFontName) { 150 return getFileNameFromPlatformName(componentFontName); 151 } 152 153 /** 154 * Returns the component font name (face name plus charset) of the 155 * font that should be used for AWT text components. 156 */ getTextComponentFontName(String familyName, int style)157 public String getTextComponentFontName(String familyName, int style) { 158 FontDescriptor[] fontDescriptors = getFontDescriptors(familyName, style); 159 String fontName = findFontWithCharset(fontDescriptors, textInputCharset); 160 if ((fontName == null) && !textInputCharset.equals("DEFAULT_CHARSET")) { 161 fontName = findFontWithCharset(fontDescriptors, "DEFAULT_CHARSET"); 162 } 163 if (fontName == null) { 164 fontName = (fontDescriptors.length > 0) ? fontDescriptors[0].getNativeName() 165 : "Arial,ANSI_CHARSET"; 166 } 167 return fontName; 168 } 169 findFontWithCharset(FontDescriptor[] fontDescriptors, String charset)170 private String findFontWithCharset(FontDescriptor[] fontDescriptors, String charset) { 171 String fontName = null; 172 for (int i = 0; i < fontDescriptors.length; i++) { 173 String componentFontName = fontDescriptors[i].getNativeName(); 174 if (componentFontName.endsWith(charset)) { 175 fontName = componentFontName; 176 } 177 } 178 return fontName; 179 } 180 181 private static HashMap<String, String> subsetCharsetMap = new HashMap<>(); 182 private static HashMap<String, String> subsetEncodingMap = new HashMap<>(); 183 private static String textInputCharset; 184 initTables(String defaultEncoding)185 private void initTables(String defaultEncoding) { 186 subsetCharsetMap.put("alphabetic", "ANSI_CHARSET"); 187 subsetCharsetMap.put("alphabetic/1252", "ANSI_CHARSET"); 188 subsetCharsetMap.put("alphabetic/default", "DEFAULT_CHARSET"); 189 subsetCharsetMap.put("arabic", "ARABIC_CHARSET"); 190 subsetCharsetMap.put("chinese-ms936", "GB2312_CHARSET"); 191 subsetCharsetMap.put("chinese-gb18030", "GB2312_CHARSET"); 192 subsetCharsetMap.put("chinese-ms950", "CHINESEBIG5_CHARSET"); 193 subsetCharsetMap.put("chinese-hkscs", "CHINESEBIG5_CHARSET"); 194 subsetCharsetMap.put("cyrillic", "RUSSIAN_CHARSET"); 195 subsetCharsetMap.put("devanagari", "DEFAULT_CHARSET"); 196 subsetCharsetMap.put("dingbats", "SYMBOL_CHARSET"); 197 subsetCharsetMap.put("greek", "GREEK_CHARSET"); 198 subsetCharsetMap.put("hebrew", "HEBREW_CHARSET"); 199 subsetCharsetMap.put("japanese", "SHIFTJIS_CHARSET"); 200 subsetCharsetMap.put("korean", "HANGEUL_CHARSET"); 201 subsetCharsetMap.put("latin", "ANSI_CHARSET"); 202 subsetCharsetMap.put("symbol", "SYMBOL_CHARSET"); 203 subsetCharsetMap.put("thai", "THAI_CHARSET"); 204 205 subsetEncodingMap.put("alphabetic", "default"); 206 subsetEncodingMap.put("alphabetic/1252", "windows-1252"); 207 subsetEncodingMap.put("alphabetic/default", defaultEncoding); 208 subsetEncodingMap.put("arabic", "windows-1256"); 209 subsetEncodingMap.put("chinese-ms936", "GBK"); 210 subsetEncodingMap.put("chinese-gb18030", "GB18030"); 211 if ("x-MS950-HKSCS".equals(defaultEncoding)) { 212 subsetEncodingMap.put("chinese-ms950", "x-MS950-HKSCS"); 213 } else { 214 subsetEncodingMap.put("chinese-ms950", "x-windows-950"); //MS950 215 } 216 subsetEncodingMap.put("chinese-hkscs", "sun.awt.HKSCS"); 217 subsetEncodingMap.put("cyrillic", "windows-1251"); 218 subsetEncodingMap.put("devanagari", "UTF-16LE"); 219 subsetEncodingMap.put("dingbats", "sun.awt.windows.WingDings"); 220 subsetEncodingMap.put("greek", "windows-1253"); 221 subsetEncodingMap.put("hebrew", "windows-1255"); 222 subsetEncodingMap.put("japanese", "windows-31j"); 223 subsetEncodingMap.put("korean", "x-windows-949"); 224 subsetEncodingMap.put("latin", "windows-1252"); 225 subsetEncodingMap.put("symbol", "sun.awt.Symbol"); 226 subsetEncodingMap.put("thai", "x-windows-874"); 227 228 if ("windows-1256".equals(defaultEncoding)) { 229 textInputCharset = "ARABIC_CHARSET"; 230 } else if ("GBK".equals(defaultEncoding)) { 231 textInputCharset = "GB2312_CHARSET"; 232 } else if ("GB18030".equals(defaultEncoding)) { 233 textInputCharset = "GB2312_CHARSET"; 234 } else if ("x-windows-950".equals(defaultEncoding)) { 235 textInputCharset = "CHINESEBIG5_CHARSET"; 236 } else if ("x-MS950-HKSCS".equals(defaultEncoding)) { 237 textInputCharset = "CHINESEBIG5_CHARSET"; 238 } else if ("windows-1251".equals(defaultEncoding)) { 239 textInputCharset = "RUSSIAN_CHARSET"; 240 } else if ("UTF-8".equals(defaultEncoding)) { 241 textInputCharset = "DEFAULT_CHARSET"; 242 } else if ("windows-1253".equals(defaultEncoding)) { 243 textInputCharset = "GREEK_CHARSET"; 244 } else if ("windows-1255".equals(defaultEncoding)) { 245 textInputCharset = "HEBREW_CHARSET"; 246 } else if ("windows-31j".equals(defaultEncoding)) { 247 textInputCharset = "SHIFTJIS_CHARSET"; 248 } else if ("x-windows-949".equals(defaultEncoding)) { 249 textInputCharset = "HANGEUL_CHARSET"; 250 } else if ("x-windows-874".equals(defaultEncoding)) { 251 textInputCharset = "THAI_CHARSET"; 252 } else { 253 textInputCharset = "DEFAULT_CHARSET"; 254 } 255 } 256 } 257