1 /* 2 * Copyright (c) 2000, 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 package sun.font; 27 28 import sun.awt.FontConfiguration; 29 import sun.awt.X11FontManager; 30 import sun.font.FontUtilities; 31 import sun.font.SunFontManager; 32 import sun.util.logging.PlatformLogger; 33 34 import java.io.File; 35 import java.io.FileInputStream; 36 import java.nio.charset.Charset; 37 import java.util.HashMap; 38 import java.util.HashSet; 39 import java.util.Properties; 40 import java.util.Scanner; 41 42 public class MFontConfiguration extends FontConfiguration { 43 44 private static FontConfiguration fontConfig = null; 45 private static PlatformLogger logger; 46 47 public MFontConfiguration(SunFontManager fm) { 48 super(fm); 49 if (FontUtilities.debugFonts()) { 50 logger = PlatformLogger.getLogger("sun.awt.FontConfiguration"); 51 } 52 initTables(); 53 } 54 55 56 public MFontConfiguration(SunFontManager fm, 57 boolean preferLocaleFonts, 58 boolean preferPropFonts) { 59 super(fm, preferLocaleFonts, preferPropFonts); 60 if (FontUtilities.debugFonts()) { 61 logger = PlatformLogger.getLogger("sun.awt.FontConfiguration"); 62 } 63 initTables(); 64 } 65 66 /* Needs to be kept in sync with updates in the languages used in 67 * the fontconfig files. 68 */ 69 protected void initReorderMap() { 70 reorderMap = new HashMap<>(); 71 if (osName == null) { /* null means SunOS */ 72 initReorderMapForSolaris(); 73 } else { 74 initReorderMapForLinux(); 75 } 76 } 77 78 private void initReorderMapForSolaris() { 79 /* Don't create a no-op entry, so we can optimize this case 80 * i.e. we don't need to do anything so can avoid slower paths in 81 * the code. 82 */ 83 // reorderMap.put("UTF-8", "latin-1"); 84 reorderMap.put("UTF-8.hi", "devanagari"); // NB is in Lucida. 85 reorderMap.put("UTF-8.ja", 86 split("japanese-x0201,japanese-x0208,japanese-x0212")); 87 reorderMap.put("UTF-8.ko", "korean-johab"); 88 reorderMap.put("UTF-8.th", "thai"); 89 reorderMap.put("UTF-8.zh.TW", "chinese-big5"); 90 reorderMap.put("UTF-8.zh.HK", split("chinese-big5,chinese-hkscs")); 91 if (FontUtilities.isSolaris8) { 92 reorderMap.put("UTF-8.zh.CN", split("chinese-gb2312,chinese-big5")); 93 } else { 94 reorderMap.put("UTF-8.zh.CN", 95 split("chinese-gb18030-0,chinese-gb18030-1")); 96 } 97 reorderMap.put("UTF-8.zh", 98 split("chinese-big5,chinese-hkscs,chinese-gb18030-0,chinese-gb18030-1")); 99 reorderMap.put("Big5", "chinese-big5"); 100 reorderMap.put("Big5-HKSCS", split("chinese-big5,chinese-hkscs")); 101 if (! FontUtilities.isSolaris8 && ! FontUtilities.isSolaris9) { 102 reorderMap.put("GB2312", split("chinese-gbk,chinese-gb2312")); 103 } else { 104 reorderMap.put("GB2312","chinese-gb2312"); 105 } 106 reorderMap.put("x-EUC-TW", 107 split("chinese-cns11643-1,chinese-cns11643-2,chinese-cns11643-3")); 108 reorderMap.put("GBK", "chinese-gbk"); 109 reorderMap.put("GB18030",split("chinese-gb18030-0,chinese-gb18030-1")); 110 111 reorderMap.put("TIS-620", "thai"); 112 reorderMap.put("x-PCK", 113 split("japanese-x0201,japanese-x0208,japanese-x0212")); 114 reorderMap.put("x-eucJP-Open", 115 split("japanese-x0201,japanese-x0208,japanese-x0212")); 116 reorderMap.put("EUC-KR", "korean"); 117 /* Don't create a no-op entry, so we can optimize this case */ 118 // reorderMap.put("ISO-8859-1", "latin-1"); 119 reorderMap.put("ISO-8859-2", "latin-2"); 120 reorderMap.put("ISO-8859-5", "cyrillic-iso8859-5"); 121 reorderMap.put("windows-1251", "cyrillic-cp1251"); 122 reorderMap.put("KOI8-R", "cyrillic-koi8-r"); 123 reorderMap.put("ISO-8859-6", "arabic"); 124 reorderMap.put("ISO-8859-7", "greek"); 125 reorderMap.put("ISO-8859-8", "hebrew"); 126 reorderMap.put("ISO-8859-9", "latin-5"); 127 reorderMap.put("ISO-8859-13", "latin-7"); 128 reorderMap.put("ISO-8859-15", "latin-9"); 129 } 130 131 private void initReorderMapForLinux() { 132 reorderMap.put("UTF-8.ja.JP", "japanese-iso10646"); 133 reorderMap.put("UTF-8.ko.KR", "korean-iso10646"); 134 reorderMap.put("UTF-8.zh.TW", "chinese-tw-iso10646"); 135 reorderMap.put("UTF-8.zh.HK", "chinese-tw-iso10646"); 136 reorderMap.put("UTF-8.zh.CN", "chinese-cn-iso10646"); 137 reorderMap.put("x-euc-jp-linux", 138 split("japanese-x0201,japanese-x0208")); 139 reorderMap.put("GB2312", "chinese-gb18030"); 140 reorderMap.put("Big5", "chinese-big5"); 141 reorderMap.put("EUC-KR", "korean"); 142 if (osName.equals("Sun")){ 143 reorderMap.put("GB18030", "chinese-cn-iso10646"); 144 } 145 else { 146 reorderMap.put("GB18030", "chinese-gb18030"); 147 } 148 } 149 150 /** 151 * Sets the OS name and version from environment information. 152 */ 153 protected void setOsNameAndVersion(){ 154 super.setOsNameAndVersion(); 155 156 if (osName.equals("SunOS")) { 157 //don't care os name on Solaris 158 osName = null; 159 } else if (osName.equals("Linux")) { 160 try { 161 File f; 162 if ((f = new File("/etc/fedora-release")).canRead()) { 163 osName = "Fedora"; 164 osVersion = getVersionString(f); 165 } else if ((f = new File("/etc/redhat-release")).canRead()) { 166 osName = "RedHat"; 167 osVersion = getVersionString(f); 168 } else if ((f = new File("/etc/turbolinux-release")).canRead()) { 169 osName = "Turbo"; 170 osVersion = getVersionString(f); 171 } else if ((f = new File("/etc/SuSE-release")).canRead()) { 172 osName = "SuSE"; 173 osVersion = getVersionString(f); 174 } else if ((f = new File("/etc/lsb-release")).canRead()) { 175 /* Ubuntu and (perhaps others) use only lsb-release. 176 * Syntax and encoding is compatible with java properties. 177 * For Ubuntu the ID is "Ubuntu". 178 */ 179 Properties props = new Properties(); 180 props.load(new FileInputStream(f)); 181 osName = props.getProperty("DISTRIB_ID"); 182 osVersion = props.getProperty("DISTRIB_RELEASE"); 183 } 184 } catch (Exception e) { 185 } 186 } 187 return; 188 } 189 190 /** 191 * Gets the OS version string from a Linux release-specific file. 192 */ 193 private String getVersionString(File f){ 194 try { 195 Scanner sc = new Scanner(f); 196 return sc.findInLine("(\\d)+((\\.)(\\d)+)*"); 197 } 198 catch (Exception e){ 199 } 200 return null; 201 } 202 203 private static final String fontsDirPrefix = "$JRE_LIB_FONTS"; 204 205 protected String mapFileName(String fileName) { 206 if (fileName != null && fileName.startsWith(fontsDirPrefix)) { 207 return SunFontManager.jreFontDirName 208 + fileName.substring(fontsDirPrefix.length()); 209 } 210 return fileName; 211 } 212 213 // overrides FontConfiguration.getFallbackFamilyName 214 public String getFallbackFamilyName(String fontName, String defaultFallback) { 215 // maintain compatibility with old font.properties files, which 216 // either had aliases for TimesRoman & Co. or defined mappings for them. 217 String compatibilityName = getCompatibilityFamilyName(fontName); 218 if (compatibilityName != null) { 219 return compatibilityName; 220 } 221 return defaultFallback; 222 } 223 224 protected String getEncoding(String awtFontName, 225 String characterSubsetName) { 226 // extract encoding field from XLFD 227 int beginIndex = 0; 228 int fieldNum = 13; // charset registry field 229 while (fieldNum-- > 0 && beginIndex >= 0) { 230 beginIndex = awtFontName.indexOf("-", beginIndex) + 1; 231 } 232 if (beginIndex == -1) { 233 return "default"; 234 } 235 String xlfdEncoding = awtFontName.substring(beginIndex); 236 if (xlfdEncoding.indexOf("fontspecific") > 0) { 237 if (awtFontName.indexOf("dingbats") > 0) { 238 return "sun.font.X11Dingbats"; 239 } else if (awtFontName.indexOf("symbol") > 0) { 240 return "sun.awt.Symbol"; 241 } 242 } 243 String encoding = encodingMap.get(xlfdEncoding); 244 if (encoding == null) { 245 encoding = "default"; 246 } 247 return encoding; 248 } 249 250 protected Charset getDefaultFontCharset(String fontName) { 251 return Charset.forName("ISO8859_1"); 252 } 253 254 protected String getFaceNameFromComponentFontName(String componentFontName) { 255 return null; 256 } 257 258 protected String getFileNameFromComponentFontName(String componentFontName) { 259 // for X11, component font name is XLFD 260 // if we have a file name already, just use it; otherwise let's see 261 // what the graphics environment can provide 262 String fileName = getFileNameFromPlatformName(componentFontName); 263 if (fileName != null && fileName.charAt(0) == '/' && 264 !needToSearchForFile(fileName)) { 265 return fileName; 266 } 267 return ((X11FontManager) fontManager).getFileNameFromXLFD(componentFontName); 268 } 269 270 public HashSet<String> getAWTFontPathSet() { 271 HashSet<String> fontDirs = new HashSet<String>(); 272 short[] scripts = getCoreScripts(0); 273 for (int i = 0; i< scripts.length; i++) { 274 String path = getString(table_awtfontpaths[scripts[i]]); 275 if (path != null) { 276 int start = 0; 277 int colon = path.indexOf(':'); 278 while (colon >= 0) { 279 fontDirs.add(path.substring(start, colon)); 280 start = colon + 1; 281 colon = path.indexOf(':', start); 282 } 283 fontDirs.add((start == 0) ? path : path.substring(start)); 284 } 285 } 286 return fontDirs; 287 } 288 289 /* methods for table setup ***********************************************/ 290 291 private static HashMap<String, String> encodingMap = new HashMap<>(); 292 293 private void initTables() { 294 // encodingMap maps XLFD encoding component to 295 // name of corresponding java.nio charset 296 encodingMap.put("iso8859-1", "ISO-8859-1"); 297 encodingMap.put("iso8859-2", "ISO-8859-2"); 298 encodingMap.put("iso8859-4", "ISO-8859-4"); 299 encodingMap.put("iso8859-5", "ISO-8859-5"); 300 encodingMap.put("iso8859-6", "ISO-8859-6"); 301 encodingMap.put("iso8859-7", "ISO-8859-7"); 302 encodingMap.put("iso8859-8", "ISO-8859-8"); 303 encodingMap.put("iso8859-9", "ISO-8859-9"); 304 encodingMap.put("iso8859-13", "ISO-8859-13"); 305 encodingMap.put("iso8859-15", "ISO-8859-15"); 306 encodingMap.put("gb2312.1980-0", "sun.font.X11GB2312"); 307 if (osName == null) { 308 // use standard converter on Solaris 309 encodingMap.put("gbk-0", "GBK"); 310 } else { 311 encodingMap.put("gbk-0", "sun.font.X11GBK"); 312 } 313 encodingMap.put("gb18030.2000-0", "sun.font.X11GB18030_0"); 314 encodingMap.put("gb18030.2000-1", "sun.font.X11GB18030_1"); 315 encodingMap.put("cns11643-1", "sun.font.X11CNS11643P1"); 316 encodingMap.put("cns11643-2", "sun.font.X11CNS11643P2"); 317 encodingMap.put("cns11643-3", "sun.font.X11CNS11643P3"); 318 encodingMap.put("big5-1", "Big5"); 319 encodingMap.put("big5-0", "Big5"); 320 encodingMap.put("hkscs-1", "Big5-HKSCS"); 321 encodingMap.put("ansi-1251", "windows-1251"); 322 encodingMap.put("koi8-r", "KOI8-R"); 323 encodingMap.put("jisx0201.1976-0", "JIS0201"); 324 encodingMap.put("jisx0208.1983-0", "JIS0208"); 325 encodingMap.put("jisx0212.1990-0", "JIS0212"); 326 encodingMap.put("ksc5601.1987-0", "sun.font.X11KSC5601"); 327 encodingMap.put("ksc5601.1992-3", "sun.font.X11Johab"); 328 encodingMap.put("tis620.2533-0", "TIS-620"); 329 encodingMap.put("iso10646-1", "UTF-16BE"); 330 } 331 332 }