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