0N/A/*
3909N/A * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.awt.motif;
0N/A
0N/Aimport java.awt.Font;
0N/Aimport java.io.BufferedReader;
0N/Aimport java.io.File;
0N/Aimport java.io.FileInputStream;
0N/Aimport java.io.InputStreamReader;
1696N/Aimport java.nio.charset.Charset;
0N/Aimport java.util.HashMap;
0N/Aimport java.util.HashSet;
0N/Aimport java.util.Locale;
0N/Aimport java.util.Properties;
0N/Aimport java.util.Scanner;
0N/Aimport sun.awt.FontConfiguration;
1686N/Aimport sun.awt.X11FontManager;
0N/Aimport sun.awt.X11GraphicsEnvironment;
1686N/Aimport sun.font.FontManager;
1686N/Aimport sun.font.SunFontManager;
1686N/Aimport sun.font.FontManagerFactory;
1686N/Aimport sun.font.FontUtilities;
0N/Aimport sun.java2d.SunGraphicsEnvironment;
1696N/Aimport sun.util.logging.PlatformLogger;
0N/A
0N/Apublic class MFontConfiguration extends FontConfiguration {
0N/A
0N/A private static FontConfiguration fontConfig = null;
1696N/A private static PlatformLogger logger;
0N/A
1686N/A public MFontConfiguration(SunFontManager fm) {
1686N/A super(fm);
1686N/A if (FontUtilities.debugFonts()) {
1696N/A logger = PlatformLogger.getLogger("sun.awt.FontConfiguration");
0N/A }
0N/A initTables();
0N/A }
0N/A
0N/A
1686N/A public MFontConfiguration(SunFontManager fm,
0N/A boolean preferLocaleFonts,
0N/A boolean preferPropFonts) {
1686N/A super(fm, preferLocaleFonts, preferPropFonts);
1686N/A if (FontUtilities.debugFonts()) {
1696N/A logger = PlatformLogger.getLogger("sun.awt.FontConfiguration");
0N/A }
0N/A initTables();
0N/A }
0N/A
0N/A /* Needs to be kept in sync with updates in the languages used in
0N/A * the fontconfig files.
0N/A */
0N/A protected void initReorderMap() {
0N/A reorderMap = new HashMap();
0N/A if (osName == null) { /* null means SunOS */
0N/A initReorderMapForSolaris();
0N/A } else {
0N/A initReorderMapForLinux();
0N/A }
0N/A }
0N/A
0N/A private void initReorderMapForSolaris() {
0N/A /* Don't create a no-op entry, so we can optimize this case
0N/A * i.e. we don't need to do anything so can avoid slower paths in
0N/A * the code.
0N/A */
0N/A// reorderMap.put("UTF-8", "latin-1");
0N/A reorderMap.put("UTF-8.hi", "devanagari"); // NB is in Lucida.
0N/A reorderMap.put("UTF-8.ja",
0N/A split("japanese-x0201,japanese-x0208,japanese-x0212"));
0N/A reorderMap.put("UTF-8.ko", "korean-johab");
0N/A reorderMap.put("UTF-8.th", "thai");
0N/A reorderMap.put("UTF-8.zh.TW", "chinese-big5");
0N/A reorderMap.put("UTF-8.zh.HK", split("chinese-big5,chinese-hkscs"));
1686N/A if (FontUtilities.isSolaris8) {
0N/A reorderMap.put("UTF-8.zh.CN", split("chinese-gb2312,chinese-big5"));
0N/A } else {
0N/A reorderMap.put("UTF-8.zh.CN",
0N/A split("chinese-gb18030-0,chinese-gb18030-1"));
0N/A }
0N/A reorderMap.put("UTF-8.zh",
0N/A split("chinese-big5,chinese-hkscs,chinese-gb18030-0,chinese-gb18030-1"));
0N/A reorderMap.put("Big5", "chinese-big5");
0N/A reorderMap.put("Big5-HKSCS", split("chinese-big5,chinese-hkscs"));
1686N/A if (! FontUtilities.isSolaris8 && ! FontUtilities.isSolaris9) {
0N/A reorderMap.put("GB2312", split("chinese-gbk,chinese-gb2312"));
0N/A } else {
0N/A reorderMap.put("GB2312","chinese-gb2312");
0N/A }
0N/A reorderMap.put("x-EUC-TW",
0N/A split("chinese-cns11643-1,chinese-cns11643-2,chinese-cns11643-3"));
0N/A reorderMap.put("GBK", "chinese-gbk");
0N/A reorderMap.put("GB18030",split("chinese-gb18030-0,chinese-gb18030-1"));
0N/A
0N/A reorderMap.put("TIS-620", "thai");
0N/A reorderMap.put("x-PCK",
0N/A split("japanese-x0201,japanese-x0208,japanese-x0212"));
0N/A reorderMap.put("x-eucJP-Open",
0N/A split("japanese-x0201,japanese-x0208,japanese-x0212"));
0N/A reorderMap.put("EUC-KR", "korean");
0N/A /* Don't create a no-op entry, so we can optimize this case */
0N/A// reorderMap.put("ISO-8859-1", "latin-1");
0N/A reorderMap.put("ISO-8859-2", "latin-2");
0N/A reorderMap.put("ISO-8859-5", "cyrillic-iso8859-5");
0N/A reorderMap.put("windows-1251", "cyrillic-cp1251");
0N/A reorderMap.put("KOI8-R", "cyrillic-koi8-r");
0N/A reorderMap.put("ISO-8859-6", "arabic");
0N/A reorderMap.put("ISO-8859-7", "greek");
0N/A reorderMap.put("ISO-8859-8", "hebrew");
0N/A reorderMap.put("ISO-8859-9", "latin-5");
0N/A reorderMap.put("ISO-8859-13", "latin-7");
0N/A reorderMap.put("ISO-8859-15", "latin-9");
0N/A }
0N/A
0N/A private void initReorderMapForLinux() {
0N/A reorderMap.put("UTF-8.ja.JP", "japanese-iso10646");
0N/A reorderMap.put("UTF-8.ko.KR", "korean-iso10646");
0N/A reorderMap.put("UTF-8.zh.TW", "chinese-tw-iso10646");
0N/A reorderMap.put("UTF-8.zh.HK", "chinese-tw-iso10646");
0N/A reorderMap.put("UTF-8.zh.CN", "chinese-cn-iso10646");
0N/A reorderMap.put("x-euc-jp-linux",
0N/A split("japanese-x0201,japanese-x0208"));
0N/A reorderMap.put("GB2312", "chinese-gb18030");
0N/A reorderMap.put("Big5", "chinese-big5");
0N/A reorderMap.put("EUC-KR", "korean");
0N/A if (osName.equals("Sun")){
0N/A reorderMap.put("GB18030", "chinese-cn-iso10646");
0N/A }
0N/A else {
0N/A reorderMap.put("GB18030", "chinese-gb18030");
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Sets the OS name and version from environment information.
0N/A */
0N/A protected void setOsNameAndVersion(){
0N/A super.setOsNameAndVersion();
0N/A
0N/A if (osName.equals("SunOS")) {
0N/A //don't care os name on Solaris
0N/A osName = null;
0N/A } else if (osName.equals("Linux")) {
0N/A try {
0N/A File f;
3359N/A if ((f = new File("/etc/fedora-release")).canRead()) {
0N/A osName = "Fedora";
0N/A osVersion = getVersionString(f);
0N/A } else if ((f = new File("/etc/redhat-release")).canRead()) {
0N/A osName = "RedHat";
0N/A osVersion = getVersionString(f);
0N/A } else if ((f = new File("/etc/turbolinux-release")).canRead()) {
0N/A osName = "Turbo";
0N/A osVersion = getVersionString(f);
0N/A } else if ((f = new File("/etc/SuSE-release")).canRead()) {
0N/A osName = "SuSE";
0N/A osVersion = getVersionString(f);
0N/A } else if ((f = new File("/etc/lsb-release")).canRead()) {
0N/A /* Ubuntu and (perhaps others) use only lsb-release.
0N/A * Syntax and encoding is compatible with java properties.
0N/A * For Ubuntu the ID is "Ubuntu".
0N/A */
0N/A Properties props = new Properties();
0N/A props.load(new FileInputStream(f));
0N/A osName = props.getProperty("DISTRIB_ID");
0N/A osVersion = props.getProperty("DISTRIB_RELEASE");
0N/A }
0N/A } catch (Exception e) {
0N/A }
0N/A }
0N/A return;
0N/A }
0N/A
0N/A /**
0N/A * Gets the OS version string from a Linux release-specific file.
0N/A */
0N/A private String getVersionString(File f){
0N/A try {
0N/A Scanner sc = new Scanner(f);
0N/A return sc.findInLine("(\\d)+((\\.)(\\d)+)*");
0N/A }
0N/A catch (Exception e){
0N/A }
0N/A return null;
0N/A }
0N/A
0N/A private static final String fontsDirPrefix = "$JRE_LIB_FONTS";
0N/A
0N/A protected String mapFileName(String fileName) {
0N/A if (fileName != null && fileName.startsWith(fontsDirPrefix)) {
1686N/A return SunFontManager.jreFontDirName
0N/A + fileName.substring(fontsDirPrefix.length());
0N/A }
0N/A return fileName;
0N/A }
0N/A
0N/A // overrides FontConfiguration.getFallbackFamilyName
0N/A public String getFallbackFamilyName(String fontName, String defaultFallback) {
0N/A // maintain compatibility with old font.properties files, which
0N/A // either had aliases for TimesRoman & Co. or defined mappings for them.
0N/A String compatibilityName = getCompatibilityFamilyName(fontName);
0N/A if (compatibilityName != null) {
0N/A return compatibilityName;
0N/A }
0N/A return defaultFallback;
0N/A }
0N/A
0N/A protected String getEncoding(String awtFontName,
0N/A String characterSubsetName) {
0N/A // extract encoding field from XLFD
0N/A int beginIndex = 0;
0N/A int fieldNum = 13; // charset registry field
0N/A while (fieldNum-- > 0 && beginIndex >= 0) {
0N/A beginIndex = awtFontName.indexOf("-", beginIndex) + 1;
0N/A }
0N/A if (beginIndex == -1) {
0N/A return "default";
0N/A }
0N/A String xlfdEncoding = awtFontName.substring(beginIndex);
0N/A if (xlfdEncoding.indexOf("fontspecific") > 0) {
0N/A if (awtFontName.indexOf("dingbats") > 0) {
0N/A return "sun.awt.motif.X11Dingbats";
0N/A } else if (awtFontName.indexOf("symbol") > 0) {
0N/A return "sun.awt.Symbol";
0N/A }
0N/A }
0N/A String encoding = (String) encodingMap.get(xlfdEncoding);
0N/A if (encoding == null) {
0N/A encoding = "default";
0N/A }
0N/A return encoding;
0N/A }
0N/A
0N/A protected Charset getDefaultFontCharset(String fontName) {
0N/A return Charset.forName("ISO8859_1");
0N/A }
0N/A
0N/A /* methods for Motif support *********************************************/
0N/A
0N/A private String[][] motifFontSets = new String[NUM_FONTS][NUM_STYLES];
0N/A
0N/A public String getMotifFontSet(String fontName, int style) {
0N/A assert isLogicalFontFamilyName(fontName);
0N/A fontName = fontName.toLowerCase(Locale.ENGLISH);
0N/A int fontIndex = getFontIndex(fontName);
0N/A int styleIndex = getStyleIndex(style);
0N/A return getMotifFontSet(fontIndex, styleIndex);
0N/A }
0N/A
0N/A private String getMotifFontSet(int fontIndex, int styleIndex) {
0N/A String fontSet = motifFontSets[fontIndex][styleIndex];
0N/A if (fontSet == null) {
0N/A fontSet = buildMotifFontSet(fontIndex, styleIndex);
0N/A motifFontSets[fontIndex][styleIndex] = fontSet;
0N/A }
0N/A return fontSet;
0N/A }
0N/A
0N/A private String buildMotifFontSet(int fontIndex, int styleIndex) {
0N/A StringBuilder buffer = new StringBuilder();
0N/A short[] scripts = getCoreScripts(fontIndex);
0N/A for (int i = 0; i < scripts.length; i++) {
0N/A short nameID = getComponentFontIDMotif(scripts[i], fontIndex, styleIndex);
0N/A if (nameID == 0) {
0N/A nameID = getComponentFontID(scripts[i], fontIndex, styleIndex);
0N/A }
0N/A String name = getComponentFontName(nameID);
0N/A if (name == null || name.endsWith("fontspecific")) {
0N/A continue;
0N/A }
0N/A if (buffer.length() > 0) {
0N/A buffer.append(',');
0N/A }
0N/A buffer.append(name);
0N/A }
0N/A return buffer.toString();
0N/A }
0N/A
0N/A protected String getFaceNameFromComponentFontName(String componentFontName) {
0N/A return null;
0N/A }
0N/A
0N/A protected String getFileNameFromComponentFontName(String componentFontName) {
0N/A // for X11, component font name is XLFD
0N/A // if we have a file name already, just use it; otherwise let's see
0N/A // what the graphics environment can provide
0N/A String fileName = getFileNameFromPlatformName(componentFontName);
0N/A if (fileName != null && fileName.charAt(0) == '/' &&
0N/A !needToSearchForFile(fileName)) {
0N/A return fileName;
0N/A }
1686N/A return ((X11FontManager) fontManager).getFileNameFromXLFD(componentFontName);
0N/A }
0N/A
0N/A /**
0N/A * Get default font for Motif widgets to use, preventing them from
0N/A * wasting time accessing inappropriate X resources. This is called
0N/A * only from native code.
0N/A *
0N/A * This is part of a Motif specific performance enhancement. By
0N/A * default, when Motif widgets are created and initialized, Motif will
0N/A * set up default fonts for the widgets, which we ALWAYS override.
0N/A * This set up includes finding the default font in the widget's X
0N/A * resources and fairly expensive requests of the X server to identify
0N/A * the specific font or fontset. We avoid all of this overhead by
0N/A * providing a well known font to use at the creation of widgets, where
0N/A * possible.
0N/A *
0N/A * The X11 fonts are specified by XLFD strings which have %d as a
0N/A * marker to indicate where the fontsize should be substituted. [The
0N/A * libc function sprintf() is used to replace it.] The value 140
0N/A * specifies a font size of 14 points.
0N/A */
0N/A private static String getDefaultMotifFontSet() {
0N/A String font = ((MFontConfiguration) getFontConfiguration()).getMotifFontSet("sansserif", Font.PLAIN);
0N/A if (font != null) {
0N/A int i;
0N/A while ((i = font.indexOf("%d")) >= 0) {
0N/A font = font.substring(0, i) + "140" + font.substring(i+2);
0N/A }
0N/A }
0N/A return font;
0N/A }
0N/A
0N/A public HashSet<String> getAWTFontPathSet() {
0N/A HashSet<String> fontDirs = new HashSet<String>();
0N/A short[] scripts = getCoreScripts(0);
0N/A for (int i = 0; i< scripts.length; i++) {
0N/A String path = getString(table_awtfontpaths[scripts[i]]);
0N/A if (path != null) {
0N/A int start = 0;
0N/A int colon = path.indexOf(':');
0N/A while (colon >= 0) {
0N/A fontDirs.add(path.substring(start, colon));
0N/A start = colon + 1;
0N/A colon = path.indexOf(':', start);
0N/A }
0N/A fontDirs.add((start == 0) ? path : path.substring(start));
0N/A }
0N/A }
0N/A return fontDirs;
0N/A }
0N/A
0N/A /* methods for table setup ***********************************************/
0N/A
0N/A private static HashMap encodingMap = new HashMap();
0N/A
0N/A private void initTables() {
0N/A // encodingMap maps XLFD encoding component to
0N/A // name of corresponding java.nio charset
0N/A encodingMap.put("iso8859-1", "ISO-8859-1");
0N/A encodingMap.put("iso8859-2", "ISO-8859-2");
0N/A encodingMap.put("iso8859-4", "ISO-8859-4");
0N/A encodingMap.put("iso8859-5", "ISO-8859-5");
0N/A encodingMap.put("iso8859-6", "ISO-8859-6");
0N/A encodingMap.put("iso8859-7", "ISO-8859-7");
0N/A encodingMap.put("iso8859-8", "ISO-8859-8");
0N/A encodingMap.put("iso8859-9", "ISO-8859-9");
0N/A encodingMap.put("iso8859-13", "ISO-8859-13");
0N/A encodingMap.put("iso8859-15", "ISO-8859-15");
0N/A encodingMap.put("gb2312.1980-0", "sun.awt.motif.X11GB2312");
0N/A if (osName == null) {
0N/A // use standard converter on Solaris
0N/A encodingMap.put("gbk-0", "GBK");
0N/A } else {
0N/A encodingMap.put("gbk-0", "sun.awt.motif.X11GBK");
0N/A }
0N/A encodingMap.put("gb18030.2000-0", "sun.awt.motif.X11GB18030_0");
0N/A encodingMap.put("gb18030.2000-1", "sun.awt.motif.X11GB18030_1");
0N/A encodingMap.put("cns11643-1", "sun.awt.motif.X11CNS11643P1");
0N/A encodingMap.put("cns11643-2", "sun.awt.motif.X11CNS11643P2");
0N/A encodingMap.put("cns11643-3", "sun.awt.motif.X11CNS11643P3");
0N/A encodingMap.put("big5-1", "Big5");
0N/A encodingMap.put("big5-0", "Big5");
0N/A encodingMap.put("hkscs-1", "Big5-HKSCS");
0N/A encodingMap.put("ansi-1251", "windows-1251");
0N/A encodingMap.put("koi8-r", "KOI8-R");
0N/A encodingMap.put("jisx0201.1976-0", "sun.awt.motif.X11JIS0201");
0N/A encodingMap.put("jisx0208.1983-0", "sun.awt.motif.X11JIS0208");
0N/A encodingMap.put("jisx0212.1990-0", "sun.awt.motif.X11JIS0212");
0N/A encodingMap.put("ksc5601.1987-0", "sun.awt.motif.X11KSC5601");
0N/A encodingMap.put("ksc5601.1992-3", "sun.awt.motif.X11Johab");
0N/A encodingMap.put("tis620.2533-0", "TIS-620");
0N/A encodingMap.put("iso10646-1", "UTF-16BE");
0N/A }
0N/A
0N/A}