Source Code Cross Referenced for FontConfiguration.java in  » 6.0-JDK-Modules-sun » awt » sun » awt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules sun » awt » sun.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package sun.awt;
0027:
0028:        import java.awt.Font;
0029:        import java.io.DataInputStream;
0030:        import java.io.DataOutputStream;
0031:        import java.io.File;
0032:        import java.io.FileInputStream;
0033:        import java.io.FileOutputStream;
0034:        import java.io.InputStream;
0035:        import java.io.IOException;
0036:        import java.io.OutputStream;
0037:        import java.nio.charset.Charset;
0038:        import java.nio.charset.CharsetEncoder;
0039:        import java.security.AccessController;
0040:        import java.security.PrivilegedAction;
0041:        import java.util.logging.Logger;
0042:        import java.util.HashMap;
0043:        import java.util.HashSet;
0044:        import java.util.Hashtable;
0045:        import java.util.Iterator;
0046:        import java.util.Locale;
0047:        import java.util.Map.Entry;
0048:        import java.util.Properties;
0049:        import java.util.Set;
0050:        import java.util.Vector;
0051:        import sun.font.CompositeFontDescriptor;
0052:        import sun.java2d.SunGraphicsEnvironment;
0053:
0054:        /**
0055:         * Provides the definitions of the five logical fonts: Serif, SansSerif,
0056:         * Monospaced, Dialog, and DialogInput. The necessary information
0057:         * is obtained from fontconfig files.
0058:         */
0059:        public abstract class FontConfiguration {
0060:
0061:            //static global runtime env
0062:            protected static String osVersion;
0063:            protected static String osName;
0064:            protected static String encoding; // canonical name of default nio charset
0065:            protected static Locale startupLocale = null;
0066:            protected static Hashtable localeMap = null;
0067:            private static FontConfiguration fontConfig;
0068:            private static Logger logger;
0069:            protected static boolean isProperties = true;
0070:
0071:            protected SunGraphicsEnvironment environment;
0072:            protected boolean preferLocaleFonts;
0073:            protected boolean preferPropFonts;
0074:
0075:            /* A default FontConfiguration must be created before an alternate
0076:             * one to ensure proper static initialisation takes place.
0077:             */
0078:            public FontConfiguration(SunGraphicsEnvironment environment) {
0079:                if (SunGraphicsEnvironment.debugFonts && logger == null) {
0080:                    logger = Logger.getLogger("sun.awt.FontConfiguration");
0081:                }
0082:                this .environment = environment;
0083:                this .preferLocaleFonts = false;
0084:                this .preferPropFonts = false;
0085:                setOsNameAndVersion(); /* static initialization */
0086:                setEncoding(); /* static initialization */
0087:                fontConfig = this ; /* static initialization */
0088:
0089:                readFontConfigFile();
0090:                initFontConfig();
0091:            }
0092:
0093:            public FontConfiguration(SunGraphicsEnvironment environment,
0094:                    boolean preferLocaleFonts, boolean preferPropFonts) {
0095:                this .environment = environment;
0096:                this .preferLocaleFonts = preferLocaleFonts;
0097:                this .preferPropFonts = preferPropFonts;
0098:                /* fontConfig should be initialised by default constructor, and
0099:                 * its data tables can be shared, since readFontConfigFile doesn't
0100:                 * update any other state. Also avoid a doPrivileged block.
0101:                 */
0102:                initFontConfig();
0103:            }
0104:
0105:            /**
0106:             * Fills in this instance's osVersion and osName members. By
0107:             * default uses the system properties os.name and os.version;
0108:             * subclasses may override.
0109:             */
0110:            protected void setOsNameAndVersion() {
0111:                osName = System.getProperty("os.name");
0112:                osVersion = System.getProperty("os.version");
0113:            }
0114:
0115:            private void setEncoding() {
0116:                encoding = Charset.defaultCharset().name();
0117:                startupLocale = SunToolkit.getStartupLocale();
0118:            }
0119:
0120:            /////////////////////////////////////////////////////////////////////
0121:            // methods for loading the FontConfig file                         //
0122:            /////////////////////////////////////////////////////////////////////
0123:            private void readFontConfigFile() {
0124:                // Find fontconfig file
0125:                File f = null;
0126:                String javaHome = System.getProperty("java.home");
0127:                if (javaHome == null) {
0128:                    throw new Error("java.home property not set");
0129:                }
0130:                String javaLib = javaHome + File.separator + "lib";
0131:                String userConfigFile = System
0132:                        .getProperty("sun.awt.fontconfig");
0133:                if (userConfigFile != null) {
0134:                    f = new File(userConfigFile);
0135:                } else {
0136:                    f = findFontConfigFile(javaLib);
0137:                }
0138:
0139:                /* This is invoked here as readFontConfigFile is only invoked
0140:                 * once per VM, and always in a privileged context, thus the
0141:                 * directory containing installed fall back fonts is accessed
0142:                 * from this context
0143:                 */
0144:                getInstalledFallbackFonts(javaLib);
0145:
0146:                if (f != null) {
0147:                    try {
0148:                        FileInputStream in = new FileInputStream(f.getPath());
0149:                        if (isProperties) {
0150:                            loadProperties(in);
0151:                        } else {
0152:                            loadBinary(in);
0153:                        }
0154:                        in.close();
0155:                        if (SunGraphicsEnvironment.debugFonts) {
0156:                            logger
0157:                                    .config("Read logical font configuration from "
0158:                                            + f);
0159:                        }
0160:                    } catch (IOException e) {
0161:                        if (SunGraphicsEnvironment.debugFonts) {
0162:                            logger
0163:                                    .config("Failed to read logical font configuration from "
0164:                                            + f);
0165:                        }
0166:                    }
0167:                }
0168:                String version = getVersion();
0169:                if (!"1".equals(version) && SunGraphicsEnvironment.debugFonts) {
0170:                    logger.config("Unsupported fontconfig version: " + version);
0171:                }
0172:            }
0173:
0174:            private void getInstalledFallbackFonts(String javaLib) {
0175:                String fallbackDirName = javaLib + File.separator + "fonts"
0176:                        + File.separator + "fallback";
0177:
0178:                File fallbackDir = new File(fallbackDirName);
0179:                if (fallbackDir.exists() && fallbackDir.isDirectory()) {
0180:                    String[] ttfs = fallbackDir
0181:                            .list(SunGraphicsEnvironment.ttFilter);
0182:                    String[] t1s = fallbackDir
0183:                            .list(SunGraphicsEnvironment.t1Filter);
0184:                    int numTTFs = (ttfs == null) ? 0 : ttfs.length;
0185:                    int numT1s = (t1s == null) ? 0 : t1s.length;
0186:                    int len = numTTFs + numT1s;
0187:                    if (numTTFs + numT1s == 0) {
0188:                        return;
0189:                    }
0190:                    installedFallbackFontFiles = new String[len];
0191:                    for (int i = 0; i < numTTFs; i++) {
0192:                        installedFallbackFontFiles[i] = fallbackDir
0193:                                + File.separator + ttfs[i];
0194:                    }
0195:                    for (int i = 0; i < numT1s; i++) {
0196:                        installedFallbackFontFiles[i + numTTFs] = fallbackDir
0197:                                + File.separator + t1s[i];
0198:                    }
0199:                    environment.registerFontsInDir(fallbackDirName);
0200:                }
0201:            }
0202:
0203:            private File findImpl(String fname) {
0204:                File f = new File(fname + ".properties");
0205:                if (f.canRead()) {
0206:                    isProperties = true;
0207:                    return f;
0208:                }
0209:                f = new File(fname + ".bfc");
0210:                if (f.canRead()) {
0211:                    isProperties = false;
0212:                    return f;
0213:                }
0214:                return null;
0215:            }
0216:
0217:            private File findFontConfigFile(String javaLib) {
0218:                String baseName = javaLib + File.separator + "fontconfig";
0219:                File configFile;
0220:                if (osVersion != null && osName != null) {
0221:                    configFile = findImpl(baseName + "." + osName + "."
0222:                            + osVersion);
0223:                    if (configFile != null) {
0224:                        return configFile;
0225:                    }
0226:                }
0227:                if (osName != null) {
0228:                    configFile = findImpl(baseName + "." + osName);
0229:                    if (configFile != null) {
0230:                        return configFile;
0231:                    }
0232:                }
0233:                if (osVersion != null) {
0234:                    configFile = findImpl(baseName + "." + osVersion);
0235:                    if (configFile != null) {
0236:                        return configFile;
0237:                    }
0238:                }
0239:                configFile = findImpl(baseName);
0240:                if (configFile != null) {
0241:                    return configFile;
0242:                }
0243:                return null;
0244:            }
0245:
0246:            /* Initialize the internal data tables from binary format font 
0247:             * configuration file.
0248:             */
0249:            public static void loadBinary(InputStream inStream)
0250:                    throws IOException {
0251:                DataInputStream in = new DataInputStream(inStream);
0252:                head = readShortTable(in, HEAD_LENGTH);
0253:                int[] tableSizes = new int[INDEX_TABLEEND];
0254:                for (int i = 0; i < INDEX_TABLEEND; i++) {
0255:                    tableSizes[i] = head[i + 1] - head[i];
0256:                }
0257:                table_scriptIDs = readShortTable(in,
0258:                        tableSizes[INDEX_scriptIDs]);
0259:                table_scriptFonts = readShortTable(in,
0260:                        tableSizes[INDEX_scriptFonts]);
0261:                table_elcIDs = readShortTable(in, tableSizes[INDEX_elcIDs]);
0262:                table_sequences = readShortTable(in,
0263:                        tableSizes[INDEX_sequences]);
0264:                table_fontfileNameIDs = readShortTable(in,
0265:                        tableSizes[INDEX_fontfileNameIDs]);
0266:                table_componentFontNameIDs = readShortTable(in,
0267:                        tableSizes[INDEX_componentFontNameIDs]);
0268:                table_filenames = readShortTable(in,
0269:                        tableSizes[INDEX_filenames]);
0270:                table_awtfontpaths = readShortTable(in,
0271:                        tableSizes[INDEX_awtfontpaths]);
0272:                table_exclusions = readShortTable(in,
0273:                        tableSizes[INDEX_exclusions]);
0274:                table_proportionals = readShortTable(in,
0275:                        tableSizes[INDEX_proportionals]);
0276:                table_scriptFontsMotif = readShortTable(in,
0277:                        tableSizes[INDEX_scriptFontsMotif]);
0278:                table_alphabeticSuffix = readShortTable(in,
0279:                        tableSizes[INDEX_alphabeticSuffix]);
0280:                table_stringIDs = readShortTable(in,
0281:                        tableSizes[INDEX_stringIDs]);
0282:
0283:                //StringTable cache
0284:                stringCache = new String[table_stringIDs.length + 1];
0285:
0286:                int len = tableSizes[INDEX_stringTable];
0287:                byte[] bb = new byte[len * 2];
0288:                table_stringTable = new char[len];
0289:                in.read(bb);
0290:                int i = 0, j = 0;
0291:                while (i < len) {
0292:                    table_stringTable[i++] = (char) (bb[j++] << 8 | (bb[j++] & 0xff));
0293:                }
0294:                if (verbose) {
0295:                    dump();
0296:                }
0297:            }
0298:
0299:            /* Generate a binary format font configuration from internal data
0300:             * tables.
0301:             */
0302:            public static void saveBinary(OutputStream out) throws IOException {
0303:                DataOutputStream dataOut = new DataOutputStream(out);
0304:                writeShortTable(dataOut, head);
0305:                writeShortTable(dataOut, table_scriptIDs);
0306:                writeShortTable(dataOut, table_scriptFonts);
0307:                writeShortTable(dataOut, table_elcIDs);
0308:                writeShortTable(dataOut, table_sequences);
0309:                writeShortTable(dataOut, table_fontfileNameIDs);
0310:                writeShortTable(dataOut, table_componentFontNameIDs);
0311:                writeShortTable(dataOut, table_filenames);
0312:                writeShortTable(dataOut, table_awtfontpaths);
0313:                writeShortTable(dataOut, table_exclusions);
0314:                writeShortTable(dataOut, table_proportionals);
0315:                writeShortTable(dataOut, table_scriptFontsMotif);
0316:                writeShortTable(dataOut, table_alphabeticSuffix);
0317:                writeShortTable(dataOut, table_stringIDs);
0318:                //stringTable
0319:                dataOut.writeChars(new String(table_stringTable));
0320:                out.close();
0321:                if (verbose) {
0322:                    dump();
0323:                }
0324:                sanityCheck();
0325:            }
0326:
0327:            //private static boolean loadingProperties;
0328:            private static short stringIDNum;
0329:            private static short[] stringIDs;
0330:            private static StringBuilder stringTable;
0331:
0332:            public static void loadProperties(InputStream in)
0333:                    throws IOException {
0334:                //loadingProperties = true;
0335:                //StringID starts from "1", "0" is reserved for "not defined"
0336:                stringIDNum = 1;
0337:                stringIDs = new short[1000];
0338:                stringTable = new StringBuilder(4096);
0339:
0340:                if (verbose && logger == null) {
0341:                    logger = Logger.getLogger("sun.awt.FontConfiguration");
0342:                }
0343:                new PropertiesHandler().load(in);
0344:
0345:                //loadingProperties = false;
0346:                stringIDs = null;
0347:                stringTable = null;
0348:            }
0349:
0350:            /////////////////////////////////////////////////////////////////////
0351:            // methods for initializing the FontConfig                         //
0352:            /////////////////////////////////////////////////////////////////////
0353:
0354:            /**
0355:             *  set initLocale, initEncoding and initELC for this FontConfig object
0356:             *  currently we just simply use the startup locale and encoding
0357:             */
0358:            private void initFontConfig() {
0359:                initLocale = startupLocale;
0360:                initEncoding = encoding;
0361:                if (preferLocaleFonts && !willReorderForStartupLocale()) {
0362:                    preferLocaleFonts = false;
0363:                }
0364:                initELC = getInitELC();
0365:                initAllComponentFonts();
0366:            }
0367:
0368:            //"ELC" stands for "Encoding.Language.Country". This method returns
0369:            //the ID of the matched elc setting of "initLocale" in elcIDs table.
0370:            //If no match is found, it returns the default ID, which is 
0371:            //"NULL.NULL.NULL" in elcIDs table.
0372:            private short getInitELC() {
0373:                if (initELC != -1) {
0374:                    return initELC;
0375:                }
0376:                HashMap<String, Integer> elcIDs = new HashMap<String, Integer>();
0377:                for (int i = 0; i < table_elcIDs.length; i++) {
0378:                    elcIDs.put(getString(table_elcIDs[i]), i);
0379:                }
0380:                String language = initLocale.getLanguage();
0381:                String country = initLocale.getCountry();
0382:                String elc;
0383:                if (elcIDs.containsKey(elc = initEncoding + "." + language
0384:                        + "." + country)
0385:                        || elcIDs.containsKey(elc = initEncoding + "."
0386:                                + language)
0387:                        || elcIDs.containsKey(elc = initEncoding)) {
0388:                    initELC = elcIDs.get(elc).shortValue();
0389:                } else {
0390:                    initELC = elcIDs.get("NULL.NULL.NULL").shortValue();
0391:                }
0392:                int i = 0;
0393:                while (i < table_alphabeticSuffix.length) {
0394:                    if (initELC == table_alphabeticSuffix[i]) {
0395:                        alphabeticSuffix = getString(table_alphabeticSuffix[i + 1]);
0396:                        return initELC;
0397:                    }
0398:                    i += 2;
0399:                }
0400:                return initELC;
0401:            }
0402:
0403:            public static boolean verbose;
0404:            private short initELC = -1;
0405:            private Locale initLocale;
0406:            private String initEncoding;
0407:            private String alphabeticSuffix;
0408:
0409:            private short[][][] compFontNameIDs = new short[NUM_FONTS][NUM_STYLES][];
0410:            private int[][][] compExclusions = new int[NUM_FONTS][][];
0411:            private int[] compCoreNum = new int[NUM_FONTS];
0412:
0413:            private Set<Short> coreFontNameIDs = new HashSet<Short>();
0414:            private Set<Short> fallbackFontNameIDs = new HashSet<Short>();
0415:
0416:            private void initAllComponentFonts() {
0417:                short[] fallbackScripts = getFallbackScripts();
0418:                for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) {
0419:                    short[] coreScripts = getCoreScripts(fontIndex);
0420:                    compCoreNum[fontIndex] = coreScripts.length;
0421:                    /* 
0422:                    System.out.println("coreScriptID=" + table_sequences[initELC * 5 + fontIndex]);
0423:                    for (int i = 0; i < coreScripts.length; i++) {
0424:                    System.out.println("  " + i + " :" + getString(table_scriptIDs[coreScripts[i]]));
0425:                    }
0426:                     */
0427:                    //init exclusionRanges
0428:                    int[][] exclusions = new int[coreScripts.length][];
0429:                    for (int i = 0; i < coreScripts.length; i++) {
0430:                        exclusions[i] = getExclusionRanges(coreScripts[i]);
0431:                    }
0432:                    compExclusions[fontIndex] = exclusions;
0433:                    //init componentFontNames
0434:                    for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) {
0435:                        int index;
0436:                        short[] nameIDs = new short[coreScripts.length
0437:                                + fallbackScripts.length];
0438:                        //core
0439:                        for (index = 0; index < coreScripts.length; index++) {
0440:                            nameIDs[index] = getComponentFontID(
0441:                                    coreScripts[index], fontIndex, styleIndex);
0442:                            if (preferLocaleFonts
0443:                                    && localeMap != null
0444:                                    && sun.font.FontManager
0445:                                            .usingAlternateFontforJALocales()) {
0446:                                nameIDs[index] = remapLocaleMap(fontIndex,
0447:                                        styleIndex, coreScripts[index],
0448:                                        nameIDs[index]);
0449:                            }
0450:                            if (preferPropFonts) {
0451:                                nameIDs[index] = remapProportional(fontIndex,
0452:                                        nameIDs[index]);
0453:                            }
0454:                            //System.out.println("nameid=" + nameIDs[index]); 
0455:                            coreFontNameIDs.add(nameIDs[index]);
0456:                        }
0457:                        //fallback
0458:                        for (int i = 0; i < fallbackScripts.length; i++) {
0459:                            short id = getComponentFontID(fallbackScripts[i],
0460:                                    fontIndex, styleIndex);
0461:                            if (preferLocaleFonts
0462:                                    && localeMap != null
0463:                                    && sun.font.FontManager
0464:                                            .usingAlternateFontforJALocales()) {
0465:                                id = remapLocaleMap(fontIndex, styleIndex,
0466:                                        fallbackScripts[i], id);
0467:                            }
0468:                            if (preferPropFonts) {
0469:                                id = remapProportional(fontIndex, id);
0470:                            }
0471:                            if (contains(nameIDs, id, index)) {
0472:                                continue;
0473:                            }
0474:                            /*
0475:                              System.out.println("fontIndex=" + fontIndex + ", styleIndex=" + styleIndex 
0476:                                    	   + ", fbIndex=" + i + ",fbS=" + fallbackScripts[i] + ", id=" + id);
0477:                             */
0478:                            fallbackFontNameIDs.add(id);
0479:                            nameIDs[index++] = id;
0480:                        }
0481:                        if (index < nameIDs.length) {
0482:                            short[] newNameIDs = new short[index];
0483:                            System.arraycopy(nameIDs, 0, newNameIDs, 0, index);
0484:                            nameIDs = newNameIDs;
0485:                        }
0486:                        compFontNameIDs[fontIndex][styleIndex] = nameIDs;
0487:                    }
0488:                }
0489:            }
0490:
0491:            private short remapLocaleMap(int fontIndex, int styleIndex,
0492:                    short scriptID, short fontID) {
0493:                String scriptName = getString(table_scriptIDs[scriptID]);
0494:
0495:                String value = (String) localeMap.get(scriptName);
0496:                if (value == null) {
0497:                    String fontName = fontNames[fontIndex];
0498:                    String styleName = styleNames[styleIndex];
0499:                    value = (String) localeMap.get(fontName + "." + styleName
0500:                            + "." + scriptName);
0501:                }
0502:                if (value == null) {
0503:                    return fontID;
0504:                }
0505:
0506:                for (int i = 0; i < table_componentFontNameIDs.length; i++) {
0507:                    String name = getString(table_componentFontNameIDs[i]);
0508:                    if (value.equalsIgnoreCase(name)) {
0509:                        fontID = (short) i;
0510:                        break;
0511:                    }
0512:                }
0513:                return fontID;
0514:            }
0515:
0516:            public static boolean hasMonoToPropMap() {
0517:                return table_proportionals != null
0518:                        && table_proportionals.length != 0;
0519:            }
0520:
0521:            private short remapProportional(int fontIndex, short id) {
0522:                if (preferPropFonts && table_proportionals.length != 0
0523:                        && fontIndex != 2 && //"monospaced"
0524:                        fontIndex != 4) { //"dialoginput"
0525:                    int i = 0;
0526:                    while (i < table_proportionals.length) {
0527:                        if (table_proportionals[i] == id) {
0528:                            return table_proportionals[i + 1];
0529:                        }
0530:                        i += 2;
0531:                    }
0532:                }
0533:                return id;
0534:            }
0535:
0536:            /////////////////////////////////////////////////////////////////////
0537:            // Methods for handling font and style names                       //
0538:            /////////////////////////////////////////////////////////////////////
0539:            protected static final int NUM_FONTS = 5;
0540:            protected static final int NUM_STYLES = 4;
0541:            private static final String[] fontNames = { "serif", "sansserif",
0542:                    "monospaced", "dialog", "dialoginput" };
0543:            private static final String[] publicFontNames = { Font.SERIF,
0544:                    Font.SANS_SERIF, Font.MONOSPACED, Font.DIALOG,
0545:                    Font.DIALOG_INPUT };
0546:            private static final String[] styleNames = { "plain", "bold",
0547:                    "italic", "bolditalic" };
0548:
0549:            /**
0550:             * Checks whether the given font family name is a valid logical font name.
0551:             * The check is case insensitive.
0552:             */
0553:            public static boolean isLogicalFontFamilyName(String fontName) {
0554:                return isLogicalFontFamilyNameLC(fontName
0555:                        .toLowerCase(Locale.ENGLISH));
0556:            }
0557:
0558:            /**
0559:             * Checks whether the given font family name is a valid logical font name.
0560:             * The check is case sensitive.
0561:             */
0562:            public static boolean isLogicalFontFamilyNameLC(String fontName) {
0563:                for (int i = 0; i < fontNames.length; i++) {
0564:                    if (fontName.equals(fontNames[i])) {
0565:                        return true;
0566:                    }
0567:                }
0568:                return false;
0569:            }
0570:
0571:            /**
0572:             * Checks whether the given style name is a valid logical font style name.
0573:             */
0574:            private static boolean isLogicalFontStyleName(String styleName) {
0575:                for (int i = 0; i < styleNames.length; i++) {
0576:                    if (styleName.equals(styleNames[i])) {
0577:                        return true;
0578:                    }
0579:                }
0580:                return false;
0581:            }
0582:
0583:            /**
0584:             * Checks whether the given font face name is a valid logical font name.
0585:             * The check is case insensitive.
0586:             */
0587:            public static boolean isLogicalFontFaceName(String fontName) {
0588:                return isLogicalFontFaceNameLC(fontName
0589:                        .toLowerCase(Locale.ENGLISH));
0590:            }
0591:
0592:            /**
0593:             * Checks whether the given font face name is a valid logical font name.
0594:             * The check is case sensitive.
0595:             */
0596:            public static boolean isLogicalFontFaceNameLC(String fontName) {
0597:                int period = fontName.indexOf('.');
0598:                if (period >= 0) {
0599:                    String familyName = fontName.substring(0, period);
0600:                    String styleName = fontName.substring(period + 1);
0601:                    return isLogicalFontFamilyName(familyName)
0602:                            && isLogicalFontStyleName(styleName);
0603:                } else {
0604:                    return isLogicalFontFamilyName(fontName);
0605:                }
0606:            }
0607:
0608:            protected static int getFontIndex(String fontName) {
0609:                return getArrayIndex(fontNames, fontName);
0610:            }
0611:
0612:            protected static int getStyleIndex(String styleName) {
0613:                return getArrayIndex(styleNames, styleName);
0614:            }
0615:
0616:            private static int getArrayIndex(String[] names, String name) {
0617:                for (int i = 0; i < names.length; i++) {
0618:                    if (name.equals(names[i])) {
0619:                        return i;
0620:                    }
0621:                }
0622:                assert false;
0623:                return 0;
0624:            }
0625:
0626:            protected static int getStyleIndex(int style) {
0627:                switch (style) {
0628:                case Font.PLAIN:
0629:                    return 0;
0630:                case Font.BOLD:
0631:                    return 1;
0632:                case Font.ITALIC:
0633:                    return 2;
0634:                case Font.BOLD | Font.ITALIC:
0635:                    return 3;
0636:                default:
0637:                    return 0;
0638:                }
0639:            }
0640:
0641:            protected static String getFontName(int fontIndex) {
0642:                return fontNames[fontIndex];
0643:            }
0644:
0645:            protected static String getStyleName(int styleIndex) {
0646:                return styleNames[styleIndex];
0647:            }
0648:
0649:            /**
0650:             * Returns the font face name for the given logical font
0651:             * family name and style.
0652:             * The style argument is interpreted as in java.awt.Font.Font.
0653:             */
0654:            public static String getLogicalFontFaceName(String familyName,
0655:                    int style) {
0656:                assert isLogicalFontFamilyName(familyName);
0657:                return familyName.toLowerCase(Locale.ENGLISH) + "."
0658:                        + getStyleString(style);
0659:            }
0660:
0661:            /**
0662:             * Returns the string typically used in properties files
0663:             * for the given style.
0664:             * The style argument is interpreted as in java.awt.Font.Font.
0665:             */
0666:            public static String getStyleString(int style) {
0667:                return getStyleName(getStyleIndex(style));
0668:            }
0669:
0670:            /**
0671:             * Returns a fallback name for the given font name. For a few known
0672:             * font names, matching logical font names are returned. For all
0673:             * other font names, defaultFallback is returned.
0674:             * defaultFallback differs between AWT and 2D.
0675:             */
0676:            public abstract String getFallbackFamilyName(String fontName,
0677:                    String defaultFallback);
0678:
0679:            /**
0680:             * Returns the 1.1 equivalent for some old 1.0 font family names for 
0681:             * which we need to maintain compatibility in some configurations.
0682:             * Returns null for other font names.
0683:             */
0684:            protected String getCompatibilityFamilyName(String fontName) {
0685:                fontName = fontName.toLowerCase(Locale.ENGLISH);
0686:                if (fontName.equals("timesroman")) {
0687:                    return "serif";
0688:                } else if (fontName.equals("helvetica")) {
0689:                    return "sansserif";
0690:                } else if (fontName.equals("courier")) {
0691:                    return "monospaced";
0692:                }
0693:                return null;
0694:            }
0695:
0696:            private static String[] installedFallbackFontFiles = null;
0697:
0698:            /**
0699:             * Maps a file name given in the font configuration file
0700:             * to a format appropriate for the platform.
0701:             */
0702:            protected String mapFileName(String fileName) {
0703:                return fileName;
0704:            }
0705:
0706:            //////////////////////////////////////////////////////////////////////
0707:            //  reordering                                                      //
0708:            //////////////////////////////////////////////////////////////////////
0709:
0710:            /* Mappings from file encoding to font config name for font supporting
0711:             * the corresponding language. This is filled in by initReorderMap() 
0712:             */
0713:            protected HashMap reorderMap = null;
0714:
0715:            /* Platform-specific mappings */
0716:            protected abstract void initReorderMap();
0717:
0718:            /* Move item at index "src" to "dst", shuffling all values in
0719:             * between down
0720:             */
0721:            private void shuffle(String[] seq, int src, int dst) {
0722:                if (dst >= src) {
0723:                    return;
0724:                }
0725:                String tmp = seq[src];
0726:                for (int i = src; i > dst; i--) {
0727:                    seq[i] = seq[i - 1];
0728:                }
0729:                seq[dst] = tmp;
0730:            }
0731:
0732:            /* Called to determine if there's a re-order sequence for this locale/
0733:             * encoding. If there's none then the caller can "bail" and avoid
0734:             * unnecessary work
0735:             */
0736:            public static boolean willReorderForStartupLocale() {
0737:                return getReorderSequence() != null;
0738:            }
0739:
0740:            private static Object getReorderSequence() {
0741:                if (fontConfig.reorderMap == null) {
0742:                    fontConfig.initReorderMap();
0743:                }
0744:                HashMap reorderMap = fontConfig.reorderMap;
0745:
0746:                /* Find the most specific mapping */
0747:                String language = startupLocale.getLanguage();
0748:                String country = startupLocale.getCountry();
0749:                Object val = reorderMap.get(encoding + "." + language + "."
0750:                        + country);
0751:                if (val == null) {
0752:                    val = reorderMap.get(encoding + "." + language);
0753:                }
0754:                if (val == null) {
0755:                    val = reorderMap.get(encoding);
0756:                }
0757:                return val;
0758:            }
0759:
0760:            /* This method reorders the sequence such that the matches for the
0761:             * file encoding are moved ahead of other elements.
0762:             * If an encoding uses more than one font, they are all moved up.
0763:             */
0764:            private void reorderSequenceForLocale(String[] seq) {
0765:                Object val = getReorderSequence();
0766:                if (val instanceof  String) {
0767:                    for (int i = 0; i < seq.length; i++) {
0768:                        if (seq[i].equals(val)) {
0769:                            shuffle(seq, i, 0);
0770:                            return;
0771:                        }
0772:                    }
0773:                } else if (val instanceof  String[]) {
0774:                    String[] fontLangs = (String[]) val;
0775:                    for (int l = 0; l < fontLangs.length; l++) {
0776:                        for (int i = 0; i < seq.length; i++) {
0777:                            if (seq[i].equals(fontLangs[l])) {
0778:                                shuffle(seq, i, l);
0779:                            }
0780:                        }
0781:                    }
0782:                }
0783:            }
0784:
0785:            private static Vector splitSequence(String sequence) {
0786:                //String.split would be more convenient, but incurs big performance penalty
0787:                Vector parts = new Vector();
0788:                int start = 0;
0789:                int end;
0790:                while ((end = sequence.indexOf(',', start)) >= 0) {
0791:                    parts.add(sequence.substring(start, end));
0792:                    start = end + 1;
0793:                }
0794:                if (sequence.length() > start) {
0795:                    parts.add(sequence.substring(start, sequence.length()));
0796:                }
0797:                return parts;
0798:            }
0799:
0800:            protected String[] split(String sequence) {
0801:                Vector v = splitSequence(sequence);
0802:                return (String[]) v.toArray(new String[0]);
0803:            }
0804:
0805:            ////////////////////////////////////////////////////////////////////////
0806:            // Methods for extracting information from the fontconfig data for AWT//
0807:            ////////////////////////////////////////////////////////////////////////
0808:            private Hashtable charsetRegistry = new Hashtable(5);
0809:
0810:            /**
0811:             * Returns FontDescriptors describing the physical fonts used for the
0812:             * given logical font name and style. The font name is interpreted
0813:             * in a case insensitive way.
0814:             * The style argument is interpreted as in java.awt.Font.Font.
0815:             */
0816:            public FontDescriptor[] getFontDescriptors(String fontName,
0817:                    int style) {
0818:                assert isLogicalFontFamilyName(fontName);
0819:                fontName = fontName.toLowerCase(Locale.ENGLISH);
0820:                int fontIndex = getFontIndex(fontName);
0821:                int styleIndex = getStyleIndex(style);
0822:                return getFontDescriptors(fontIndex, styleIndex);
0823:            }
0824:
0825:            private FontDescriptor[][][] fontDescriptors = new FontDescriptor[NUM_FONTS][NUM_STYLES][];
0826:
0827:            private FontDescriptor[] getFontDescriptors(int fontIndex,
0828:                    int styleIndex) {
0829:                FontDescriptor[] descriptors = fontDescriptors[fontIndex][styleIndex];
0830:                if (descriptors == null) {
0831:                    descriptors = buildFontDescriptors(fontIndex, styleIndex);
0832:                    fontDescriptors[fontIndex][styleIndex] = descriptors;
0833:                }
0834:                return descriptors;
0835:            }
0836:
0837:            private FontDescriptor[] buildFontDescriptors(int fontIndex,
0838:                    int styleIndex) {
0839:                String fontName = fontNames[fontIndex];
0840:                String styleName = styleNames[styleIndex];
0841:
0842:                short[] scriptIDs = getCoreScripts(fontIndex);
0843:                short[] nameIDs = compFontNameIDs[fontIndex][styleIndex];
0844:                String[] sequence = new String[scriptIDs.length];
0845:                String[] names = new String[scriptIDs.length];
0846:                for (int i = 0; i < sequence.length; i++) {
0847:                    names[i] = getComponentFontName(nameIDs[i]);
0848:                    sequence[i] = getScriptName(scriptIDs[i]);
0849:                    if (alphabeticSuffix != null
0850:                            && "alphabetic".equals(sequence[i])) {
0851:                        sequence[i] = sequence[i] + "/" + alphabeticSuffix;
0852:                    }
0853:                }
0854:                int[][] fontExclusionRanges = compExclusions[fontIndex];
0855:
0856:                FontDescriptor[] descriptors = new FontDescriptor[names.length];
0857:
0858:                for (int i = 0; i < names.length; i++) {
0859:                    String awtFontName;
0860:                    String encoding;
0861:
0862:                    awtFontName = makeAWTFontName(names[i], sequence[i]);
0863:
0864:                    // look up character encoding
0865:                    encoding = getEncoding(names[i], sequence[i]);
0866:                    if (encoding == null) {
0867:                        encoding = "default";
0868:                    }
0869:                    CharsetEncoder enc = getFontCharsetEncoder(encoding.trim(),
0870:                            awtFontName);
0871:
0872:                    // we already have the exclusion ranges
0873:                    int[] exclusionRanges = fontExclusionRanges[i];
0874:
0875:                    // create descriptor
0876:                    descriptors[i] = new FontDescriptor(awtFontName, enc,
0877:                            exclusionRanges);
0878:                }
0879:                return descriptors;
0880:            }
0881:
0882:            /**
0883:             * Returns the AWT font name for the given platform font name and
0884:             * character subset.
0885:             */
0886:            protected String makeAWTFontName(String platformFontName,
0887:                    String characterSubsetName) {
0888:                return platformFontName;
0889:            }
0890:
0891:            /**
0892:             * Returns the java.io name of the platform character encoding for the 
0893:             * given AWT font name and character subset. May return "default"
0894:             * to indicate that getDefaultFontCharset should be called to obtain
0895:             * a charset encoder.
0896:             */
0897:            protected abstract String getEncoding(String awtFontName,
0898:                    String characterSubsetName);
0899:
0900:            private CharsetEncoder getFontCharsetEncoder(
0901:                    final String charsetName, String fontName) {
0902:
0903:                Charset fc = null;
0904:                if (charsetName.equals("default")) {
0905:                    fc = (Charset) charsetRegistry.get(fontName);
0906:                } else {
0907:                    fc = (Charset) charsetRegistry.get(charsetName);
0908:                }
0909:                if (fc != null) {
0910:                    return fc.newEncoder();
0911:                }
0912:
0913:                if (!charsetName.startsWith("sun.awt.")
0914:                        && !charsetName.equals("default")) {
0915:                    fc = Charset.forName(charsetName);
0916:                } else {
0917:                    Class fcc = (Class) AccessController
0918:                            .doPrivileged(new PrivilegedAction() {
0919:                                public Object run() {
0920:                                    try {
0921:                                        return Class
0922:                                                .forName(
0923:                                                        charsetName,
0924:                                                        true,
0925:                                                        Thread
0926:                                                                .currentThread()
0927:                                                                .getContextClassLoader());
0928:                                    } catch (ClassNotFoundException e) {
0929:                                    }
0930:                                    return null;
0931:                                }
0932:                            });
0933:
0934:                    if (fcc != null) {
0935:                        try {
0936:                            fc = (Charset) fcc.newInstance();
0937:                        } catch (Exception e) {
0938:                        }
0939:                    }
0940:                }
0941:                if (fc == null) {
0942:                    fc = getDefaultFontCharset(fontName);
0943:                }
0944:
0945:                if (charsetName.equals("default")) {
0946:                    charsetRegistry.put(fontName, fc);
0947:                } else {
0948:                    charsetRegistry.put(charsetName, fc);
0949:                }
0950:                return fc.newEncoder();
0951:            }
0952:
0953:            protected abstract Charset getDefaultFontCharset(String fontName);
0954:
0955:            /* This retrieves the platform font directories (path) calculated
0956:             * by setAWTFontPathSequence(String[]). The default implementation
0957:             * returns null, its expected that X11 platforms may return
0958:             * non-null.
0959:             */
0960:            public HashSet<String> getAWTFontPathSet() {
0961:                return null;
0962:            }
0963:
0964:            ////////////////////////////////////////////////////////////////////////
0965:            // methods for extracting information from the fontconfig data for 2D //
0966:            ////////////////////////////////////////////////////////////////////////
0967:
0968:            /**
0969:             * Returns an array of composite font descriptors for all logical font
0970:             * faces.
0971:             * If the font configuration file doesn't specify Lucida Sans Regular
0972:             * or the given fallback font as component fonts, they are added here.
0973:             */
0974:            public CompositeFontDescriptor[] get2DCompositeFontInfo() {
0975:                CompositeFontDescriptor[] result = new CompositeFontDescriptor[NUM_FONTS
0976:                        * NUM_STYLES];
0977:                String defaultFontFile = environment.getDefaultFontFile();
0978:                String defaultFontFaceName = environment
0979:                        .getDefaultFontFaceName();
0980:
0981:                for (int fontIndex = 0; fontIndex < NUM_FONTS; fontIndex++) {
0982:                    String fontName = publicFontNames[fontIndex];
0983:
0984:                    // determine exclusion ranges for font
0985:                    // AWT uses separate exclusion range array per component font.
0986:                    // 2D packs all range boundaries into one array.
0987:                    // Both use separate entries for lower and upper boundary.
0988:                    int[][] exclusions = compExclusions[fontIndex];
0989:                    int numExclusionRanges = 0;
0990:                    for (int i = 0; i < exclusions.length; i++) {
0991:                        numExclusionRanges += exclusions[i].length;
0992:                    }
0993:                    int[] exclusionRanges = new int[numExclusionRanges];
0994:                    int[] exclusionRangeLimits = new int[exclusions.length];
0995:                    int exclusionRangeIndex = 0;
0996:                    int exclusionRangeLimitIndex = 0;
0997:                    for (int i = 0; i < exclusions.length; i++) {
0998:                        int[] componentRanges = exclusions[i];
0999:                        for (int j = 0; j < componentRanges.length;) {
1000:                            int value = componentRanges[j];
1001:                            exclusionRanges[exclusionRangeIndex++] = componentRanges[j++];
1002:                            exclusionRanges[exclusionRangeIndex++] = componentRanges[j++];
1003:                        }
1004:                        exclusionRangeLimits[i] = exclusionRangeIndex;
1005:                    }
1006:                    // other info is per style
1007:                    for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) {
1008:                        int maxComponentFontCount = compFontNameIDs[fontIndex][styleIndex].length;
1009:                        boolean sawDefaultFontFile = false;
1010:                        // fall back fonts listed in the lib/fonts/fallback directory
1011:                        if (installedFallbackFontFiles != null) {
1012:                            maxComponentFontCount += installedFallbackFontFiles.length;
1013:                        }
1014:                        String faceName = fontName + "."
1015:                                + styleNames[styleIndex];
1016:
1017:                        // determine face names and file names of component fonts
1018:                        String[] componentFaceNames = new String[maxComponentFontCount];
1019:                        String[] componentFileNames = new String[maxComponentFontCount];
1020:
1021:                        int index;
1022:                        for (index = 0; index < compFontNameIDs[fontIndex][styleIndex].length; index++) {
1023:                            short fontNameID = compFontNameIDs[fontIndex][styleIndex][index];
1024:                            short fileNameID = getComponentFileID(fontNameID);
1025:                            componentFaceNames[index] = getFaceNameFromComponentFontName(getComponentFontName(fontNameID));
1026:                            componentFileNames[index] = mapFileName(getComponentFileName(fileNameID));
1027:                            if (componentFileNames[index] == null
1028:                                    || needToSearchForFile(componentFileNames[index])) {
1029:                                componentFileNames[index] = getFileNameFromComponentFontName(getComponentFontName(fontNameID));
1030:                            }
1031:                            if (!sawDefaultFontFile
1032:                                    && defaultFontFile
1033:                                            .equals(componentFileNames[index])) {
1034:                                sawDefaultFontFile = true;
1035:                            }
1036:                            /*
1037:                            System.out.println(publicFontNames[fontIndex] + "." + styleNames[styleIndex] + "."
1038:                                + getString(table_scriptIDs[coreScripts[index]]) + "=" + componentFileNames[index]);
1039:                             */
1040:                        }
1041:
1042:                        //"Lucida Sans Regular" is not in the list, we add it here
1043:                        if (!sawDefaultFontFile) {
1044:                            int len = 0;
1045:                            if (installedFallbackFontFiles != null) {
1046:                                len = installedFallbackFontFiles.length;
1047:                            }
1048:                            if (index + len == maxComponentFontCount) {
1049:                                String[] newComponentFaceNames = new String[maxComponentFontCount + 1];
1050:                                System.arraycopy(componentFaceNames, 0,
1051:                                        newComponentFaceNames, 0, index);
1052:                                componentFaceNames = newComponentFaceNames;
1053:                                String[] newComponentFileNames = new String[maxComponentFontCount + 1];
1054:                                System.arraycopy(componentFileNames, 0,
1055:                                        newComponentFileNames, 0, index);
1056:                                componentFileNames = newComponentFileNames;
1057:                            }
1058:                            componentFaceNames[index] = defaultFontFaceName;
1059:                            componentFileNames[index] = defaultFontFile;
1060:                            index++;
1061:                        }
1062:
1063:                        if (installedFallbackFontFiles != null) {
1064:                            for (int ifb = 0; ifb < installedFallbackFontFiles.length; ifb++) {
1065:                                componentFaceNames[index] = null;
1066:                                componentFileNames[index] = installedFallbackFontFiles[ifb];
1067:                                index++;
1068:                            }
1069:                        }
1070:
1071:                        if (index < maxComponentFontCount) {
1072:                            String[] newComponentFaceNames = new String[index];
1073:                            System.arraycopy(componentFaceNames, 0,
1074:                                    newComponentFaceNames, 0, index);
1075:                            componentFaceNames = newComponentFaceNames;
1076:                            String[] newComponentFileNames = new String[index];
1077:                            System.arraycopy(componentFileNames, 0,
1078:                                    newComponentFileNames, 0, index);
1079:                            componentFileNames = newComponentFileNames;
1080:                        }
1081:                        // exclusion range limit array length must match component face name
1082:                        // array length - native code relies on this
1083:
1084:                        int[] clippedExclusionRangeLimits = exclusionRangeLimits;
1085:                        if (index != clippedExclusionRangeLimits.length) {
1086:                            int len = exclusionRangeLimits.length;
1087:                            clippedExclusionRangeLimits = new int[index];
1088:                            System.arraycopy(exclusionRangeLimits, 0,
1089:                                    clippedExclusionRangeLimits, 0, len);
1090:                            //padding for various fallback fonts
1091:                            for (int i = len; i < index; i++) {
1092:                                clippedExclusionRangeLimits[i] = exclusionRanges.length;
1093:                            }
1094:                        }
1095:                        /*
1096:                                System.out.println(faceName + ":");                
1097:                                for (int i = 0; i < componentFileNames.length; i++) {
1098:                                    System.out.println("    " + componentFaceNames[i] 
1099:                                         + "  -> " + componentFileNames[i]);
1100:                                }
1101:                         */
1102:                        result[fontIndex * NUM_STYLES + styleIndex] = new CompositeFontDescriptor(
1103:                                faceName, compCoreNum[fontIndex],
1104:                                componentFaceNames, componentFileNames,
1105:                                exclusionRanges, clippedExclusionRangeLimits);
1106:                    }
1107:                }
1108:                return result;
1109:            }
1110:
1111:            protected abstract String getFaceNameFromComponentFontName(
1112:                    String componentFontName);
1113:
1114:            protected abstract String getFileNameFromComponentFontName(
1115:                    String componentFontName);
1116:
1117:            /*
1118:            public class 2dFont {
1119:                public String platformName;
1120:                public String fontfileName;
1121:            }
1122:            private 2dFont [] componentFonts = null;
1123:             */
1124:
1125:            /* Used on Linux to test if a file referenced in a font configuration
1126:             * file exists in the location that is expected. If it does, no need
1127:             * to search for it. If it doesn't then unless its a fallback font,
1128:             * return that expensive code should be invoked to search for the font.
1129:             */
1130:            HashMap<String, Boolean> existsMap;
1131:
1132:            public boolean needToSearchForFile(String fileName) {
1133:                if (!environment.isLinux) {
1134:                    return false;
1135:                } else if (existsMap == null) {
1136:                    existsMap = new HashMap<String, Boolean>();
1137:                }
1138:                Boolean exists = existsMap.get(fileName);
1139:                if (exists == null) {
1140:                    /* call getNumberCoreFonts() to ensure these are initialised, and
1141:                     * if this file isn't for a core component, ie, is a for a fallback
1142:                     * font which very typically isn't available, then can't afford
1143:                     * to take the start-up penalty to search for it.
1144:                     */
1145:                    getNumberCoreFonts();
1146:                    if (!coreFontFileNames.contains(fileName)) {
1147:                        exists = Boolean.TRUE;
1148:                    } else {
1149:                        exists = Boolean.valueOf((new File(fileName)).exists());
1150:                        existsMap.put(fileName, exists);
1151:                        if (SunGraphicsEnvironment.debugFonts
1152:                                && exists == Boolean.FALSE) {
1153:                            logger.warning("Couldn't locate font file "
1154:                                    + fileName);
1155:                        }
1156:                    }
1157:                }
1158:                return exists == Boolean.FALSE;
1159:            }
1160:
1161:            private int numCoreFonts = -1;
1162:            private String[] componentFonts = null;
1163:            HashMap<String, String> filenamesMap = new HashMap<String, String>();
1164:            HashSet<String> coreFontFileNames = new HashSet<String>();
1165:
1166:            /* Return the number of core fonts. Note this isn't thread safe but
1167:             * a calling thread can call this and getPlatformFontNames() in either
1168:             * order.
1169:             */
1170:            public int getNumberCoreFonts() {
1171:                if (numCoreFonts == -1) {
1172:                    numCoreFonts = coreFontNameIDs.size();
1173:                    Short[] emptyShortArray = new Short[0];
1174:                    Short[] core = coreFontNameIDs.toArray(emptyShortArray);
1175:                    Short[] fallback = fallbackFontNameIDs
1176:                            .toArray(emptyShortArray);
1177:
1178:                    int numFallbackFonts = 0;
1179:                    int i;
1180:                    for (i = 0; i < fallback.length; i++) {
1181:                        if (coreFontNameIDs.contains(fallback[i])) {
1182:                            fallback[i] = null;
1183:                            continue;
1184:                        }
1185:                        numFallbackFonts++;
1186:                    }
1187:                    componentFonts = new String[numCoreFonts + numFallbackFonts];
1188:                    String filename = null;
1189:                    for (i = 0; i < core.length; i++) {
1190:                        short fontid = core[i];
1191:                        short fileid = getComponentFileID(fontid);
1192:                        componentFonts[i] = getComponentFontName(fontid);
1193:                        String compFileName = getComponentFileName(fileid);
1194:                        if (compFileName != null) {
1195:                            coreFontFileNames.add(compFileName);
1196:                        }
1197:                        filenamesMap.put(componentFonts[i],
1198:                                mapFileName(compFileName));
1199:                    }
1200:                    for (int j = 0; j < fallback.length; j++) {
1201:                        if (fallback[j] != null) {
1202:                            short fontid = fallback[j];
1203:                            short fileid = getComponentFileID(fontid);
1204:                            componentFonts[i] = getComponentFontName(fontid);
1205:                            filenamesMap.put(componentFonts[i],
1206:                                    mapFileName(getComponentFileName(fileid)));
1207:                            i++;
1208:                        }
1209:                    }
1210:                }
1211:                return numCoreFonts;
1212:            }
1213:
1214:            /* Return all platform font names used by this font configuration.
1215:             * The first getNumberCoreFonts() entries are guaranteed to be the
1216:             * core fonts - ie no fall back only fonts.
1217:             */
1218:            public String[] getPlatformFontNames() {
1219:                if (numCoreFonts == -1) {
1220:                    getNumberCoreFonts();
1221:                }
1222:                return componentFonts;
1223:            }
1224:
1225:            /**
1226:             * Returns a file name for the physical font represented by this platform font name,
1227:             * if the font configuration has such information available, or null if the
1228:             * information is unavailable. The file name returned is just a hint; a null return
1229:             * value doesn't necessarily mean that the font is unavailable, nor does a non-null
1230:             * return value guarantee that the file exists and contains the physical font.
1231:             * The file name can be an absolute or a relative path name.
1232:             */
1233:            public String getFileNameFromPlatformName(String platformName) {
1234:                // get2DCompositeFontInfo 
1235:                //     ->  getFileNameFromComponentfontName()  (W/M)
1236:                //       ->   getFileNameFromPlatformName()
1237:                // it's a waste of time on Win32, but I have to give X11 a chance to 
1238:                // call getFileNameFromXLFD()  
1239:                return filenamesMap.get(platformName);
1240:            }
1241:
1242:            /**
1243:             * Returns a configuration specific path to be appended to the font
1244:             * search path.
1245:             */
1246:            public String getExtraFontPath() {
1247:                return getString(head[INDEX_appendedfontpath]);
1248:            }
1249:
1250:            public String getVersion() {
1251:                return getString(head[INDEX_version]);
1252:            }
1253:
1254:            /* subclass support */
1255:            protected static FontConfiguration getFontConfiguration() {
1256:                return fontConfig;
1257:            }
1258:
1259:            //////////////////////////////////////////////////////////////////////
1260:            // FontConfig data tables and the index constants in binary file    //
1261:            //////////////////////////////////////////////////////////////////////
1262:            /* The binary font configuration file begins with a short[] "head", which
1263:             * contains the offsets to the starts of the individual data table which
1264:             * immediately follow. Teh current implemention includes the tables shown
1265:             * below.
1266:             *
1267:             * (00) table_scriptIDs    :stringIDs of all defined CharacterSubsetNames
1268:             * (01) table_scriptFonts  :scriptID x fontIndex x styleIndex-> 
1269:             *                          PlatformFontNameID mapping. Each scriptID might
1270:             *                          have 1 or 20 entries depends on if it is defined 
1271:             *                          via a "allfonts.CharacterSubsetname" or a list of
1272:             *                          "LogicalFontName.StyleName.CharacterSubsetName"
1273:             *                          entries, positive entry means it's a "allfonts" 
1274:             *                          entry, a negative value means this is a offset to
1275:             *                          a NUM_FONTS x NUM_STYLES subtable.
1276:             * (02) table_elcIDs       :stringIDs of all defined ELC names, string    
1277:             *                          "NULL.NULL.NULL" is used for "default"
1278:             * (03) table_sequences    :elcID x logicalFont -> scriptIDs table defined
1279:             *                          by "sequence.allfonts/LogicalFontName.ELC" in
1280:             *                          font configuration file, each "elcID" has 
1281:             *                          NUM_FONTS (5) entries in this table.
1282:             * (04) table_fontfileNameIDs 
1283:             *                         :stringIDs of all defined font file names
1284:             * (05) table_componentFontNameIDs
1285:             *                         :stringIDs of all defined PlatformFontNames
1286:             * (06) table_filenames    :platformFontNamesID->fontfileNameID mapping 
1287:             *                          table, the index is the platformFontNamesID.
1288:             * (07) table_awtfontpaths :CharacterSubsetNames->awtfontpaths mapping table,
1289:             *                          the index is the CharacterSubsetName's stringID 
1290:             *                          and content is the stringID of awtfontpath.
1291:             * (08) table_exclusions   :scriptID -> exclusionRanges mapping table,
1292:             *                          the index is the scriptID and the content is 
1293:                                        a id of an exclusionRanges int[].
1294:             * (09) table_proportionals:list of pairs of PlatformFontNameIDs, stores
1295:             *                          the replacement info defined by "proportional"
1296:             *                          keyword.
1297:             * (10) table_scriptFontsMotif 
1298:             *                         :same as (01) except this table stores the 
1299:             *                          info defined with ".motif" keyword
1300:             * (11) table_alphabeticSuffix
1301:             *                         :elcID -> stringID of alphabetic/XXXX entries
1302:             * (12) table_stringIDs    :The index of this table is the string ID, the 
1303:             *                          content is the "start index" of this string in 
1304:             *                          stringTable, use the start index of next entry 
1305:             *                          as the "end index".
1306:             * (13) table_stringTable  :The real storage of all character strings defined
1307:             *                          /used this font configuration, need a pair of 
1308:             *                          "start" and "end" indices to access.
1309:             * (14) reserved
1310:             * (15) table_fallbackScripts 
1311:             *                         :stringIDs of fallback CharacterSubsetnames, stored 
1312:             *                          in the order of they are defined in sequence.fallback.
1313:             * (16) table_appendedfontpath
1314:             *                         :stringtID of the "appendedfontpath" defined.
1315:             * (17) table_version   :stringID of the version number of this fontconfig file.
1316:             */
1317:            private static final int HEAD_LENGTH = 20;
1318:            private static final int INDEX_scriptIDs = 0;
1319:            private static final int INDEX_scriptFonts = 1;
1320:            private static final int INDEX_elcIDs = 2;
1321:            private static final int INDEX_sequences = 3;
1322:            private static final int INDEX_fontfileNameIDs = 4;
1323:            private static final int INDEX_componentFontNameIDs = 5;
1324:            private static final int INDEX_filenames = 6;
1325:            private static final int INDEX_awtfontpaths = 7;
1326:            private static final int INDEX_exclusions = 8;
1327:            private static final int INDEX_proportionals = 9;
1328:            private static final int INDEX_scriptFontsMotif = 10;
1329:            private static final int INDEX_alphabeticSuffix = 11;
1330:            private static final int INDEX_stringIDs = 12;
1331:            private static final int INDEX_stringTable = 13;
1332:            private static final int INDEX_TABLEEND = 14;
1333:            private static final int INDEX_fallbackScripts = 15;
1334:            private static final int INDEX_appendedfontpath = 16;
1335:            private static final int INDEX_version = 17;
1336:
1337:            private static short[] head;
1338:            private static short[] table_scriptIDs;
1339:            private static short[] table_scriptFonts;
1340:            private static short[] table_elcIDs;
1341:            private static short[] table_sequences;
1342:            private static short[] table_fontfileNameIDs;
1343:            private static short[] table_componentFontNameIDs;
1344:            private static short[] table_filenames;
1345:            protected static short[] table_awtfontpaths;
1346:            private static short[] table_exclusions;
1347:            private static short[] table_proportionals;
1348:            private static short[] table_scriptFontsMotif;
1349:            private static short[] table_alphabeticSuffix;
1350:            private static short[] table_stringIDs;
1351:            private static char[] table_stringTable;
1352:
1353:            private static void sanityCheck() {
1354:                int errors = 0;
1355:
1356:                //This method will only be called during build time, do we
1357:                //need do PrivilegedAction?
1358:                String osName = (String) java.security.AccessController
1359:                        .doPrivileged(new java.security.PrivilegedAction() {
1360:                            public Object run() {
1361:                                return System.getProperty("os.name");
1362:                            }
1363:                        });
1364:
1365:                //componentFontNameID starts from "1"
1366:                for (int ii = 1; ii < table_filenames.length; ii++) {
1367:                    if (table_filenames[ii] == -1) {
1368:                        System.out.println("\n Warning: " + "<filename."
1369:                                + getString(table_componentFontNameIDs[ii])
1370:                                + "> entry is missing!!!");
1371:                        if (!osName.contains("Linux")) {
1372:                            errors++;
1373:                        }
1374:                    }
1375:                }
1376:                for (int ii = 0; ii < table_scriptIDs.length; ii++) {
1377:                    short fid = table_scriptFonts[ii];
1378:                    if (fid == 0) {
1379:                        System.out.println("\n Error: <allfonts."
1380:                                + getString(table_scriptIDs[ii])
1381:                                + "> entry is missing!!!");
1382:                        errors++;
1383:                        continue;
1384:                    } else if (fid < 0) {
1385:                        fid = (short) -fid;
1386:                        for (int iii = 0; iii < NUM_FONTS; iii++) {
1387:                            for (int iij = 0; iij < NUM_STYLES; iij++) {
1388:                                int jj = iii * NUM_STYLES + iij;
1389:                                short ffid = table_scriptFonts[fid + jj];
1390:                                if (ffid == 0) {
1391:                                    System.out.println("\n Error: <"
1392:                                            + getFontName(iii) + "."
1393:                                            + getStyleName(iij) + "."
1394:                                            + getString(table_scriptIDs[ii])
1395:                                            + "> entry is missing!!!");
1396:                                    errors++;
1397:                                }
1398:                            }
1399:                        }
1400:                    }
1401:                }
1402:                if ("SunOS".equals(osName)) {
1403:                    for (int ii = 0; ii < table_awtfontpaths.length; ii++) {
1404:                        if (table_awtfontpaths[ii] == 0) {
1405:                            String script = getString(table_scriptIDs[ii]);
1406:                            if (script.contains("lucida")
1407:                                    || script.contains("dingbats")
1408:                                    || script.contains("symbol")) {
1409:                                continue;
1410:                            }
1411:                            System.out.println("\nError: " + "<awtfontpath."
1412:                                    + script + "> entry is missing!!!");
1413:                            errors++;
1414:                        }
1415:                    }
1416:                }
1417:                if (errors != 0) {
1418:                    System.out
1419:                            .println("!!THERE ARE "
1420:                                    + errors
1421:                                    + " ERROR(S) IN "
1422:                                    + "THE FONTCONFIG FILE, PLEASE CHECK ITS CONTENT!!\n");
1423:                    System.exit(1);
1424:
1425:                }
1426:            }
1427:
1428:            //dump the fontconfig data tables
1429:            private static void dump() {
1430:                System.out.println("\n----Head Table------------");
1431:                for (int ii = 0; ii < HEAD_LENGTH; ii++) {
1432:                    System.out.println("  " + ii + " : " + head[ii]);
1433:                }
1434:                System.out.println("\n----scriptIDs-------------");
1435:                printTable(table_scriptIDs, 0);
1436:                System.out.println("\n----scriptFonts----------------");
1437:                for (int ii = 0; ii < table_scriptIDs.length; ii++) {
1438:                    short fid = table_scriptFonts[ii];
1439:                    if (fid >= 0) {
1440:                        System.out.println("  allfonts."
1441:                                + getString(table_scriptIDs[ii]) + "="
1442:                                + getString(table_componentFontNameIDs[fid]));
1443:                    }
1444:                }
1445:                for (int ii = 0; ii < table_scriptIDs.length; ii++) {
1446:                    short fid = table_scriptFonts[ii];
1447:                    if (fid < 0) {
1448:                        fid = (short) -fid;
1449:                        for (int iii = 0; iii < NUM_FONTS; iii++) {
1450:                            for (int iij = 0; iij < NUM_STYLES; iij++) {
1451:                                int jj = iii * NUM_STYLES + iij;
1452:                                short ffid = table_scriptFonts[fid + jj];
1453:                                System.out
1454:                                        .println("  "
1455:                                                + getFontName(iii)
1456:                                                + "."
1457:                                                + getStyleName(iij)
1458:                                                + "."
1459:                                                + getString(table_scriptIDs[ii])
1460:                                                + "="
1461:                                                + getString(table_componentFontNameIDs[ffid]));
1462:                            }
1463:                        }
1464:
1465:                    }
1466:                }
1467:                System.out.println("\n----elcIDs----------------");
1468:                printTable(table_elcIDs, 0);
1469:                System.out.println("\n----sequences-------------");
1470:                for (int ii = 0; ii < table_elcIDs.length; ii++) {
1471:                    System.out.println("  " + ii + "/"
1472:                            + getString((short) table_elcIDs[ii]));
1473:                    short[] ss = getShortArray(table_sequences[ii * NUM_FONTS
1474:                            + 0]);
1475:                    for (int jj = 0; jj < ss.length; jj++) {
1476:                        System.out.println("     "
1477:                                + getString((short) table_scriptIDs[ss[jj]]));
1478:                    }
1479:                }
1480:                System.out.println("\n----fontfileNameIDs-------");
1481:                printTable(table_fontfileNameIDs, 0);
1482:
1483:                System.out.println("\n----componentFontNameIDs--");
1484:                printTable(table_componentFontNameIDs, 1);
1485:                System.out.println("\n----filenames-------------");
1486:                for (int ii = 0; ii < table_filenames.length; ii++) {
1487:                    if (table_filenames[ii] == -1) {
1488:                        System.out.println("  " + ii + " : null");
1489:                    } else {
1490:                        System.out
1491:                                .println("  "
1492:                                        + ii
1493:                                        + " : "
1494:                                        + getString(table_fontfileNameIDs[table_filenames[ii]]));
1495:                    }
1496:                }
1497:                System.out.println("\n----awtfontpaths---------");
1498:                for (int ii = 0; ii < table_awtfontpaths.length; ii++) {
1499:                    System.out.println("  " + getString(table_scriptIDs[ii])
1500:                            + " : " + getString(table_awtfontpaths[ii]));
1501:                }
1502:                System.out.println("\n----proportionals--------");
1503:                for (int ii = 0; ii < table_proportionals.length; ii++) {
1504:                    System.out
1505:                            .println("  "
1506:                                    + getString((short) table_componentFontNameIDs[table_proportionals[ii++]])
1507:                                    + " -> "
1508:                                    + getString((short) table_componentFontNameIDs[table_proportionals[ii]]));
1509:                }
1510:                int i = 0;
1511:                System.out.println("\n----alphabeticSuffix----");
1512:                while (i < table_alphabeticSuffix.length) {
1513:                    System.out
1514:                            .println("    "
1515:                                    + getString(table_elcIDs[table_alphabeticSuffix[i++]])
1516:                                    + " -> "
1517:                                    + getString(table_alphabeticSuffix[i++]));
1518:                }
1519:                System.out.println("\n----String Table---------");
1520:                System.out.println("    stringID:    Num ="
1521:                        + table_stringIDs.length);
1522:                System.out.println("    stringTable: Size="
1523:                        + table_stringTable.length * 2);
1524:
1525:                System.out.println("\n----fallbackScriptIDs---");
1526:                short[] fbsIDs = getShortArray(head[INDEX_fallbackScripts]);
1527:                for (int ii = 0; ii < fbsIDs.length; ii++) {
1528:                    System.out.println("  "
1529:                            + getString(table_scriptIDs[fbsIDs[ii]]));
1530:                }
1531:                System.out.println("\n----appendedfontpath-----");
1532:                System.out.println("  "
1533:                        + getString(head[INDEX_appendedfontpath]));
1534:                System.out.println("\n----Version--------------");
1535:                System.out.println("  " + getString(head[INDEX_version]));
1536:            }
1537:
1538:            //////////////////////////////////////////////////////////////////////
1539:            // Data table access methods                                        //
1540:            //////////////////////////////////////////////////////////////////////
1541:
1542:            /* Return the fontID of the platformFontName defined in this font config
1543:             * by "LogicalFontName.StyleName.CharacterSubsetName" entry or
1544:             * "allfonts.CharacterSubsetName" entry in properties format fc file.
1545:             */
1546:            protected static short getComponentFontID(short scriptID,
1547:                    int fontIndex, int styleIndex) {
1548:                short fid = table_scriptFonts[scriptID];
1549:                //System.out.println("fid=" + fid + "/ scriptID=" + scriptID + ", fi=" + fontIndex + ", si=" + styleIndex);
1550:                if (fid >= 0) {
1551:                    //"allfonts"
1552:                    return fid;
1553:                } else {
1554:                    return table_scriptFonts[-fid + fontIndex * NUM_STYLES
1555:                            + styleIndex];
1556:                }
1557:            }
1558:
1559:            /* Same as getCompoentFontID() except this method returns the fontID define by
1560:             * "xxxx.motif" entry.
1561:             */
1562:            protected static short getComponentFontIDMotif(short scriptID,
1563:                    int fontIndex, int styleIndex) {
1564:                if (table_scriptFontsMotif.length == 0) {
1565:                    return 0;
1566:                }
1567:                short fid = table_scriptFontsMotif[scriptID];
1568:                if (fid >= 0) {
1569:                    //"allfonts" > 0 or "not defined" == 0
1570:                    return fid;
1571:                } else {
1572:                    return table_scriptFontsMotif[-fid + fontIndex * NUM_STYLES
1573:                            + styleIndex];
1574:                }
1575:            }
1576:
1577:            private static int[] getExclusionRanges(short scriptID) {
1578:                short exID = table_exclusions[scriptID];
1579:                if (exID == 0) {
1580:                    return EMPTY_INT_ARRAY;
1581:                } else {
1582:                    char[] exChar = getString(exID).toCharArray();
1583:                    int[] exInt = new int[exChar.length / 2];
1584:                    int i = 0;
1585:                    for (int j = 0; j < exInt.length; j++) {
1586:                        exInt[j] = (exChar[i++] << 16) + (exChar[i++] & 0xffff);
1587:                    }
1588:                    return exInt;
1589:                }
1590:            }
1591:
1592:            private static boolean contains(short IDs[], short id, int limit) {
1593:                for (int i = 0; i < limit; i++) {
1594:                    if (IDs[i] == id) {
1595:                        return true;
1596:                    }
1597:                }
1598:                return false;
1599:            }
1600:
1601:            /* Return the PlatformFontName from its fontID*/
1602:            protected static String getComponentFontName(short id) {
1603:                if (id < 0) {
1604:                    return null;
1605:                }
1606:                return getString(table_componentFontNameIDs[id]);
1607:            }
1608:
1609:            private static String getComponentFileName(short id) {
1610:                if (id < 0) {
1611:                    return null;
1612:                }
1613:                return getString(table_fontfileNameIDs[id]);
1614:            }
1615:
1616:            //componentFontID -> componentFileID
1617:            private static short getComponentFileID(short nameID) {
1618:                return table_filenames[nameID];
1619:            }
1620:
1621:            private static String getScriptName(short scriptID) {
1622:                return getString(table_scriptIDs[scriptID]);
1623:            }
1624:
1625:            private HashMap<String, Short> reorderScripts;
1626:
1627:            protected short[] getCoreScripts(int fontIndex) {
1628:                short elc = getInitELC();
1629:                /*
1630:                System.out.println("getCoreScripts: elc=" + elc + ", fontIndex=" + fontIndex);
1631:                short[] ss = getShortArray(table_sequences[elc * NUM_FONTS + fontIndex]);
1632:                for (int i = 0; i < ss.length; i++) {
1633:                  System.out.println("     " + getString((short)table_scriptIDs[ss[i]])); 
1634:                }
1635:                 */
1636:                short[] scripts = getShortArray(table_sequences[elc * NUM_FONTS
1637:                        + fontIndex]);
1638:                if (preferLocaleFonts) {
1639:                    if (reorderScripts == null) {
1640:                        reorderScripts = new HashMap<String, Short>();
1641:                    }
1642:                    String[] ss = new String[scripts.length];
1643:                    for (int i = 0; i < ss.length; i++) {
1644:                        ss[i] = getScriptName(scripts[i]);
1645:                        reorderScripts.put(ss[i], scripts[i]);
1646:                    }
1647:                    reorderSequenceForLocale(ss);
1648:                    for (int i = 0; i < ss.length; i++) {
1649:                        scripts[i] = reorderScripts.get(ss[i]);
1650:                    }
1651:                }
1652:                return scripts;
1653:            }
1654:
1655:            private static short[] getFallbackScripts() {
1656:                return getShortArray(head[INDEX_fallbackScripts]);
1657:            }
1658:
1659:            private static void printTable(short[] list, int start) {
1660:                for (int i = start; i < list.length; i++) {
1661:                    System.out.println("  " + i + " : " + getString(list[i]));
1662:                }
1663:            }
1664:
1665:            private static short[] readShortTable(DataInputStream in, int len)
1666:                    throws IOException {
1667:                if (len == 0) {
1668:                    return EMPTY_SHORT_ARRAY;
1669:                }
1670:                short[] data = new short[len];
1671:                byte[] bb = new byte[len * 2];
1672:                in.read(bb);
1673:                int i = 0, j = 0;
1674:                while (i < len) {
1675:                    data[i++] = (short) (bb[j++] << 8 | (bb[j++] & 0xff));
1676:                }
1677:                return data;
1678:            }
1679:
1680:            private static void writeShortTable(DataOutputStream out,
1681:                    short[] data) throws IOException {
1682:                for (int i = 0; i < data.length; i++) {
1683:                    out.writeShort(data[i]);
1684:                }
1685:            }
1686:
1687:            private static short[] toList(HashMap map) {
1688:                short[] list = new short[map.size()];
1689:                for (int i = 0; i < list.length; i++) {
1690:                    list[i] = -1;
1691:                }
1692:                Iterator iterator = map.entrySet().iterator();
1693:                while (iterator.hasNext()) {
1694:                    Entry<String, Short> entry = (Entry<String, Short>) iterator
1695:                            .next();
1696:                    list[entry.getValue().shortValue()] = getStringID(entry
1697:                            .getKey());
1698:                }
1699:                return list;
1700:            }
1701:
1702:            //runtime cache
1703:            private static String[] stringCache;
1704:
1705:            protected static String getString(short stringID) {
1706:                if (stringID == 0)
1707:                    return null;
1708:                /*
1709:                if (loadingProperties) {
1710:                    return stringTable.substring(stringIDs[stringID], 
1711:                			 stringIDs[stringID+1]);
1712:                }
1713:                 */
1714:                //sync if we want it to be MT-enabled
1715:                if (stringCache[stringID] == null) {
1716:                    stringCache[stringID] = new String(table_stringTable,
1717:                            table_stringIDs[stringID],
1718:                            table_stringIDs[stringID + 1]
1719:                                    - table_stringIDs[stringID]);
1720:                }
1721:                return stringCache[stringID];
1722:            }
1723:
1724:            private static short[] getShortArray(short shortArrayID) {
1725:                String s = getString(shortArrayID);
1726:                char[] cc = s.toCharArray();
1727:                short[] ss = new short[cc.length];
1728:                for (int i = 0; i < cc.length; i++) {
1729:                    ss[i] = (short) (cc[i] & 0xffff);
1730:                }
1731:                return ss;
1732:            }
1733:
1734:            private static short getStringID(String s) {
1735:                if (s == null) {
1736:                    return (short) 0;
1737:                }
1738:                short pos0 = (short) stringTable.length();
1739:                stringTable.append(s);
1740:                short pos1 = (short) stringTable.length();
1741:
1742:                stringIDs[stringIDNum] = pos0;
1743:                stringIDs[stringIDNum + 1] = pos1;
1744:                stringIDNum++;
1745:                if (stringIDNum + 1 >= stringIDs.length) {
1746:                    short[] tmp = new short[stringIDNum + 1000];
1747:                    System.arraycopy(stringIDs, 0, tmp, 0, stringIDNum);
1748:                    stringIDs = tmp;
1749:                }
1750:                return (short) (stringIDNum - 1);
1751:            }
1752:
1753:            private static short getShortArrayID(short sa[]) {
1754:                char[] cc = new char[sa.length];
1755:                for (int i = 0; i < sa.length; i++) {
1756:                    cc[i] = (char) sa[i];
1757:                }
1758:                String s = new String(cc);
1759:                return getStringID(s);
1760:            }
1761:
1762:            //utility "empty" objects
1763:            private static final int[] EMPTY_INT_ARRAY = new int[0];
1764:            private static final String[] EMPTY_STRING_ARRAY = new String[0];
1765:            private static final short[] EMPTY_SHORT_ARRAY = new short[0];
1766:            private static final String UNDEFINED_COMPONENT_FONT = "unknown";
1767:
1768:            //////////////////////////////////////////////////////////////////////////
1769:            //Convert the FontConfig data in Properties file to binary data tables  //
1770:            //////////////////////////////////////////////////////////////////////////
1771:            static class PropertiesHandler {
1772:                public void load(InputStream in) throws IOException {
1773:                    initLogicalNameStyle();
1774:                    initHashMaps();
1775:                    FontProperties fp = new FontProperties();
1776:                    fp.load(in);
1777:                    initBinaryTable();
1778:                }
1779:
1780:                private void initBinaryTable() {
1781:                    //(0)
1782:                    head = new short[HEAD_LENGTH];
1783:                    head[INDEX_scriptIDs] = (short) HEAD_LENGTH;
1784:
1785:                    table_scriptIDs = toList(scriptIDs);
1786:                    //(1)a: scriptAllfonts scriptID/allfonts -> componentFontNameID
1787:                    //   b: scriptFonts    scriptID -> componentFontNameID[20]
1788:                    //if we have a "allfonts.script" def, then we just put
1789:                    //the "-platformFontID" value in the slot, otherwise the slot 
1790:                    //value is "offset" which "offset" is where 20 entries located 
1791:                    //in the table attached.
1792:                    head[INDEX_scriptFonts] = (short) (head[INDEX_scriptIDs] + table_scriptIDs.length);
1793:                    int len = table_scriptIDs.length + scriptFonts.size() * 20;
1794:                    table_scriptFonts = new short[len];
1795:
1796:                    Iterator iterator = scriptAllfonts.entrySet().iterator();
1797:                    while (iterator.hasNext()) {
1798:                        Entry<Short, Short> entry = (Entry<Short, Short>) iterator
1799:                                .next();
1800:                        table_scriptFonts[entry.getKey().intValue()] = (short) entry
1801:                                .getValue().shortValue();
1802:                    }
1803:                    int off = table_scriptIDs.length;
1804:                    iterator = scriptFonts.entrySet().iterator();
1805:                    while (iterator.hasNext()) {
1806:                        Entry<Short, Short[]> entry = (Entry<Short, Short[]>) iterator
1807:                                .next();
1808:                        table_scriptFonts[entry.getKey().intValue()] = (short) -off;
1809:                        Short[] v = entry.getValue();
1810:                        int i = 0;
1811:                        while (i < 20) {
1812:                            if (v[i] != null) {
1813:                                table_scriptFonts[off++] = v[i].shortValue();
1814:                            } else {
1815:                                table_scriptFonts[off++] = 0;
1816:                            }
1817:                            i++;
1818:                        }
1819:                    }
1820:
1821:                    //(2)
1822:                    head[INDEX_elcIDs] = (short) (head[INDEX_scriptFonts] + table_scriptFonts.length);
1823:                    table_elcIDs = toList(elcIDs);
1824:
1825:                    //(3) sequences  elcID -> XXXX[1|5] -> scriptID[]
1826:                    head[INDEX_sequences] = (short) (head[INDEX_elcIDs] + table_elcIDs.length);
1827:                    table_sequences = new short[elcIDs.size() * NUM_FONTS];
1828:                    iterator = sequences.entrySet().iterator();
1829:                    while (iterator.hasNext()) {
1830:                        Entry<Short, short[]> entry = (Entry<Short, short[]>) iterator
1831:                                .next();
1832:                        //table_sequences[entry.getKey().intValue()] = (short)-off;
1833:                        int k = entry.getKey().intValue();
1834:                        short[] v = entry.getValue();
1835:                        /*
1836:                          System.out.println("elc=" + k + "/" + getString((short)table_elcIDs[k]));
1837:                          short[] ss = getShortArray(v[0]);
1838:                          for (int i = 0; i < ss.length; i++) {
1839:                          System.out.println("     " + getString((short)table_scriptIDs[ss[i]]));
1840:                          }
1841:                         */
1842:                        if (v.length == 1) {
1843:                            //the "allfonts" entries
1844:                            for (int i = 0; i < NUM_FONTS; i++) {
1845:                                table_sequences[k * NUM_FONTS + i] = v[0];
1846:                            }
1847:                        } else {
1848:                            for (int i = 0; i < NUM_FONTS; i++) {
1849:                                table_sequences[k * NUM_FONTS + i] = v[i];
1850:                            }
1851:                        }
1852:                    }
1853:                    //(4)
1854:                    head[INDEX_fontfileNameIDs] = (short) (head[INDEX_sequences] + table_sequences.length);
1855:                    table_fontfileNameIDs = toList(fontfileNameIDs);
1856:
1857:                    //(5) 
1858:                    head[INDEX_componentFontNameIDs] = (short) (head[INDEX_fontfileNameIDs] + table_fontfileNameIDs.length);
1859:                    table_componentFontNameIDs = toList(componentFontNameIDs);
1860:
1861:                    //(6)componentFontNameID -> filenameID
1862:                    head[INDEX_filenames] = (short) (head[INDEX_componentFontNameIDs] + table_componentFontNameIDs.length);
1863:                    table_filenames = new short[table_componentFontNameIDs.length];
1864:                    for (int i = 0; i < table_filenames.length; i++) {
1865:                        table_filenames[i] = -1;
1866:                    }
1867:                    iterator = filenames.entrySet().iterator();
1868:                    while (iterator.hasNext()) {
1869:                        Entry<Short, Short> entry = (Entry<Short, Short>) iterator
1870:                                .next();
1871:                        table_filenames[entry.getKey().shortValue()] = entry
1872:                                .getValue().shortValue();
1873:                    }
1874:
1875:                    //(7)scriptID-> awtfontpath
1876:                    //the paths are stored as scriptID -> stringID in awtfontpahts 
1877:                    head[INDEX_awtfontpaths] = (short) (head[INDEX_filenames] + table_filenames.length);
1878:                    table_awtfontpaths = new short[table_scriptIDs.length];
1879:                    iterator = awtfontpaths.entrySet().iterator();
1880:                    while (iterator.hasNext()) {
1881:                        Entry<Short, Short> entry = (Entry<Short, Short>) iterator
1882:                                .next();
1883:                        table_awtfontpaths[entry.getKey().shortValue()] = entry
1884:                                .getValue().shortValue();
1885:                    }
1886:
1887:                    //(8)exclusions
1888:                    head[INDEX_exclusions] = (short) (head[INDEX_awtfontpaths] + table_awtfontpaths.length);
1889:                    table_exclusions = new short[scriptIDs.size()];
1890:                    iterator = exclusions.entrySet().iterator();
1891:                    while (iterator.hasNext()) {
1892:                        Entry<Short, int[]> entry = (Entry<Short, int[]>) iterator
1893:                                .next();
1894:                        int[] exI = entry.getValue();
1895:                        char[] exC = new char[exI.length * 2];
1896:                        int j = 0;
1897:                        for (int i = 0; i < exI.length; i++) {
1898:                            exC[j++] = (char) (exI[i] >> 16);
1899:                            exC[j++] = (char) (exI[i] & 0xffff);
1900:                        }
1901:                        table_exclusions[entry.getKey().shortValue()] = getStringID(new String(
1902:                                exC));
1903:                    }
1904:                    //(9)proportionals
1905:                    head[INDEX_proportionals] = (short) (head[INDEX_exclusions] + table_exclusions.length);
1906:                    table_proportionals = new short[proportionals.size() * 2];
1907:                    iterator = proportionals.entrySet().iterator();
1908:                    int j = 0;
1909:                    while (iterator.hasNext()) {
1910:                        Entry<Short, Short> entry = (Entry<Short, Short>) iterator
1911:                                .next();
1912:                        table_proportionals[j++] = entry.getKey().shortValue();
1913:                        table_proportionals[j++] = entry.getValue()
1914:                                .shortValue();
1915:                    }
1916:
1917:                    //(10) see (1) for info, the only difference is "xxx.motif" 
1918:                    head[INDEX_scriptFontsMotif] = (short) (head[INDEX_proportionals] + table_proportionals.length);
1919:                    if (scriptAllfontsMotif.size() != 0
1920:                            || scriptFontsMotif.size() != 0) {
1921:                        len = table_scriptIDs.length + scriptFontsMotif.size()
1922:                                * 20;
1923:                        table_scriptFontsMotif = new short[len];
1924:
1925:                        iterator = scriptAllfontsMotif.entrySet().iterator();
1926:                        while (iterator.hasNext()) {
1927:                            Entry<Short, Short> entry = (Entry<Short, Short>) iterator
1928:                                    .next();
1929:                            table_scriptFontsMotif[entry.getKey().intValue()] = (short) entry
1930:                                    .getValue().shortValue();
1931:                        }
1932:                        off = table_scriptIDs.length;
1933:                        iterator = scriptFontsMotif.entrySet().iterator();
1934:                        while (iterator.hasNext()) {
1935:                            Entry<Short, Short[]> entry = (Entry<Short, Short[]>) iterator
1936:                                    .next();
1937:                            table_scriptFontsMotif[entry.getKey().intValue()] = (short) -off;
1938:                            Short[] v = entry.getValue();
1939:                            int i = 0;
1940:                            while (i < 20) {
1941:                                if (v[i] != null) {
1942:                                    table_scriptFontsMotif[off++] = v[i]
1943:                                            .shortValue();
1944:                                } else {
1945:                                    table_scriptFontsMotif[off++] = 0;
1946:                                }
1947:                                i++;
1948:                            }
1949:                        }
1950:                    } else {
1951:                        table_scriptFontsMotif = EMPTY_SHORT_ARRAY;
1952:                    }
1953:
1954:                    //(11)short[] alphabeticSuffix
1955:                    head[INDEX_alphabeticSuffix] = (short) (head[INDEX_scriptFontsMotif] + table_scriptFontsMotif.length);
1956:                    table_alphabeticSuffix = new short[alphabeticSuffix.size() * 2];
1957:                    iterator = alphabeticSuffix.entrySet().iterator();
1958:                    j = 0;
1959:                    while (iterator.hasNext()) {
1960:                        Entry<Short, Short> entry = (Entry<Short, Short>) iterator
1961:                                .next();
1962:                        table_alphabeticSuffix[j++] = entry.getKey()
1963:                                .shortValue();
1964:                        table_alphabeticSuffix[j++] = entry.getValue()
1965:                                .shortValue();
1966:                    }
1967:
1968:                    //(15)short[] fallbackScriptIDs; just put the ID in head
1969:                    head[INDEX_fallbackScripts] = getShortArrayID(fallbackScriptIDs);
1970:
1971:                    //(16)appendedfontpath
1972:                    head[INDEX_appendedfontpath] = getStringID(appendedfontpath);
1973:
1974:                    //(17)version
1975:                    head[INDEX_version] = getStringID(version);
1976:
1977:                    //(12)short[] StringIDs
1978:                    head[INDEX_stringIDs] = (short) (head[INDEX_alphabeticSuffix] + table_alphabeticSuffix.length);
1979:                    table_stringIDs = new short[stringIDNum + 1];
1980:                    System.arraycopy(stringIDs, 0, table_stringIDs, 0,
1981:                            stringIDNum + 1);
1982:
1983:                    //(13)StringTable
1984:                    head[INDEX_stringTable] = (short) (head[INDEX_stringIDs]
1985:                            + stringIDNum + 1);
1986:                    table_stringTable = stringTable.toString().toCharArray();
1987:                    //(14)
1988:                    head[INDEX_TABLEEND] = (short) (head[INDEX_stringTable] + stringTable
1989:                            .length());
1990:
1991:                    //StringTable cache
1992:                    stringCache = new String[table_stringIDs.length];
1993:                }
1994:
1995:                //////////////////////////////////////////////
1996:                private HashMap<String, Short> scriptIDs;
1997:                //elc -> Encoding.Language.Country
1998:                private HashMap<String, Short> elcIDs;
1999:                //componentFontNameID starts from "1", "0" reserves for "undefined"
2000:                private HashMap<String, Short> componentFontNameIDs;
2001:                private HashMap<String, Short> fontfileNameIDs;
2002:                private HashMap<String, Integer> logicalFontIDs;
2003:                private HashMap<String, Integer> fontStyleIDs;
2004:
2005:                //componentFontNameID -> fontfileNameID  
2006:                private HashMap<Short, Short> filenames;
2007:
2008:                //elcID -> allfonts/logicalFont -> scriptID list
2009:                //(1)if we have a "allfonts", then the length of the 
2010:                //   value array is "1", otherwise it's 5, each font
2011:                //   must have their own individual entry.
2012:                //scriptID list "short[]" is stored as an ID
2013:                private HashMap<Short, short[]> sequences;
2014:
2015:                //scriptID ->logicFontID/fontStyleID->componentFontNameID, 
2016:                //a 20-entry array (5-name x 4-style) for each script
2017:                private HashMap<Short, Short[]> scriptFonts;
2018:
2019:                //scriptID -> componentFontNameID
2020:                private HashMap<Short, Short> scriptAllfonts;
2021:
2022:                //scriptID -> exclusionRanges[]
2023:                private HashMap<Short, int[]> exclusions;
2024:
2025:                //scriptID -> fontpath
2026:                private HashMap<Short, Short> awtfontpaths;
2027:
2028:                //fontID -> fontID
2029:                private HashMap<Short, Short> proportionals;
2030:
2031:                //scriptID -> componentFontNameID
2032:                private HashMap<Short, Short> scriptAllfontsMotif;
2033:
2034:                //scriptID ->logicFontID/fontStyleID->componentFontNameID, 
2035:                private HashMap<Short, Short[]> scriptFontsMotif;
2036:
2037:                //elcID -> stringID of alphabetic/XXXX 
2038:                private HashMap<Short, Short> alphabeticSuffix;
2039:
2040:                private short[] fallbackScriptIDs;
2041:                private String version;
2042:                private String appendedfontpath;
2043:
2044:                private void initLogicalNameStyle() {
2045:                    logicalFontIDs = new HashMap<String, Integer>();
2046:                    fontStyleIDs = new HashMap<String, Integer>();
2047:                    logicalFontIDs.put("serif", 0);
2048:                    logicalFontIDs.put("sansserif", 1);
2049:                    logicalFontIDs.put("monospaced", 2);
2050:                    logicalFontIDs.put("dialog", 3);
2051:                    logicalFontIDs.put("dialoginput", 4);
2052:                    fontStyleIDs.put("plain", 0);
2053:                    fontStyleIDs.put("bold", 1);
2054:                    fontStyleIDs.put("italic", 2);
2055:                    fontStyleIDs.put("bolditalic", 3);
2056:                }
2057:
2058:                private void initHashMaps() {
2059:                    scriptIDs = new HashMap<String, Short>();
2060:                    elcIDs = new HashMap<String, Short>();
2061:                    componentFontNameIDs = new HashMap<String, Short>();
2062:                    /*Init these tables to allow componentFontNameID, fontfileNameIDs
2063:                      to start from "1".
2064:                     */
2065:                    componentFontNameIDs.put("", new Short((short) 0));
2066:
2067:                    fontfileNameIDs = new HashMap<String, Short>();
2068:                    filenames = new HashMap<Short, Short>();
2069:                    sequences = new HashMap<Short, short[]>();
2070:                    scriptFonts = new HashMap<Short, Short[]>();
2071:                    scriptAllfonts = new HashMap<Short, Short>();
2072:                    exclusions = new HashMap<Short, int[]>();
2073:                    awtfontpaths = new HashMap<Short, Short>();
2074:                    proportionals = new HashMap<Short, Short>();
2075:                    scriptFontsMotif = new HashMap<Short, Short[]>();
2076:                    scriptAllfontsMotif = new HashMap<Short, Short>();
2077:                    alphabeticSuffix = new HashMap<Short, Short>();
2078:                    fallbackScriptIDs = EMPTY_SHORT_ARRAY;
2079:                    /*
2080:                      version
2081:                      appendedfontpath
2082:                     */
2083:                }
2084:
2085:                private int[] parseExclusions(String key, String exclusions) {
2086:                    if (exclusions == null) {
2087:                        return EMPTY_INT_ARRAY;
2088:                    }
2089:                    // range format is xxxx-XXXX,yyyyyy-YYYYYY,.....
2090:                    int numExclusions = 1;
2091:                    int pos = 0;
2092:                    while ((pos = exclusions.indexOf(',', pos)) != -1) {
2093:                        numExclusions++;
2094:                        pos++;
2095:                    }
2096:                    int[] exclusionRanges = new int[numExclusions * 2];
2097:                    pos = 0;
2098:                    int newPos = 0;
2099:                    for (int j = 0; j < numExclusions * 2;) {
2100:                        String lower, upper;
2101:                        int lo = 0, up = 0;
2102:                        try {
2103:                            newPos = exclusions.indexOf('-', pos);
2104:                            lower = exclusions.substring(pos, newPos);
2105:                            pos = newPos + 1;
2106:                            newPos = exclusions.indexOf(',', pos);
2107:                            if (newPos == -1) {
2108:                                newPos = exclusions.length();
2109:                            }
2110:                            upper = exclusions.substring(pos, newPos);
2111:                            pos = newPos + 1;
2112:                            int lowerLength = lower.length();
2113:                            int upperLength = upper.length();
2114:                            if (lowerLength != 4 && lowerLength != 6
2115:                                    || upperLength != 4 && upperLength != 6) {
2116:                                throw new Exception();
2117:                            }
2118:                            lo = Integer.parseInt(lower, 16);
2119:                            up = Integer.parseInt(upper, 16);
2120:                            if (lo > up) {
2121:                                throw new Exception();
2122:                            }
2123:                        } catch (Exception e) {
2124:                            if (SunGraphicsEnvironment.debugFonts
2125:                                    && logger != null) {
2126:                                logger.config("Failed parsing " + key
2127:                                        + " property of font configuration.");
2128:
2129:                            }
2130:                            return EMPTY_INT_ARRAY;
2131:                        }
2132:                        exclusionRanges[j++] = lo;
2133:                        exclusionRanges[j++] = up;
2134:                    }
2135:                    return exclusionRanges;
2136:                }
2137:
2138:                private Short getID(HashMap<String, Short> map, String key) {
2139:                    Short ret = map.get(key);
2140:                    if (ret == null) {
2141:                        map.put(key, (short) map.size());
2142:                        return map.get(key);
2143:                    }
2144:                    return ret;
2145:                }
2146:
2147:                class FontProperties extends Properties {
2148:                    public synchronized Object put(Object k, Object v) {
2149:                        parseProperty((String) k, (String) v);
2150:                        return null;
2151:                    }
2152:                }
2153:
2154:                private void parseProperty(String key, String value) {
2155:                    if (key.startsWith("filename.")) {
2156:                        //the only special case is "MingLiu_HKSCS" which has "_" in its
2157:                        //facename, we dont want to replace the "_" with " "
2158:                        key = key.substring(9);
2159:                        if (!"MingLiU_HKSCS".equals(key)) {
2160:                            key = key.replace('_', ' ');
2161:                        }
2162:                        Short faceID = getID(componentFontNameIDs, key);
2163:                        Short fileID = getID(fontfileNameIDs, value);
2164:                        //System.out.println("faceID=" + faceID + "/" + key + " -> "
2165:                        //    + "fileID=" + fileID + "/" + value);
2166:                        filenames.put(faceID, fileID);
2167:                    } else if (key.startsWith("exclusion.")) {
2168:                        key = key.substring(10);
2169:                        exclusions.put(getID(scriptIDs, key), parseExclusions(
2170:                                key, value));
2171:                    } else if (key.startsWith("sequence.")) {
2172:                        key = key.substring(9);
2173:                        boolean hasDefault = false;
2174:                        boolean has1252 = false;
2175:
2176:                        //get the scriptID list
2177:                        String[] ss = (String[]) splitSequence(value).toArray(
2178:                                EMPTY_STRING_ARRAY);
2179:                        short[] sa = new short[ss.length];
2180:                        for (int i = 0; i < ss.length; i++) {
2181:                            if ("alphabetic/default".equals(ss[i])) {
2182:                                //System.out.println(key + " -> " + ss[i]);
2183:                                ss[i] = "alphabetic";
2184:                                hasDefault = true;
2185:                            } else if ("alphabetic/1252".equals(ss[i])) {
2186:                                //System.out.println(key + " -> " + ss[i]);
2187:                                ss[i] = "alphabetic";
2188:                                has1252 = true;
2189:                            }
2190:                            sa[i] = getID(scriptIDs, ss[i]).shortValue();
2191:                            //System.out.println("scriptID=" + si[i] + "/" + ss[i]);
2192:                        }
2193:                        //convert the "short[] -> string -> stringID"
2194:                        short scriptArrayID = getShortArrayID(sa);
2195:                        Short elcID = null;
2196:                        int dot = key.indexOf('.');
2197:                        if (dot == -1) {
2198:                            if ("fallback".equals(key)) {
2199:                                fallbackScriptIDs = sa;
2200:                                return;
2201:                            }
2202:                            if ("allfonts".equals(key)) {
2203:                                elcID = getID(elcIDs, "NULL.NULL.NULL");
2204:                            } else {
2205:                                if (logger != null) {
2206:                                    logger
2207:                                            .config("Error sequence def: <sequence."
2208:                                                    + key + ">");
2209:                                }
2210:                                return;
2211:                            }
2212:                        } else {
2213:                            elcID = getID(elcIDs, key.substring(dot + 1));
2214:                            //System.out.println("elcID=" + elcID + "/" + key.substring(dot + 1));
2215:                            key = key.substring(0, dot);
2216:                        }
2217:                        short[] scriptArrayIDs = null;
2218:                        if ("allfonts".equals(key)) {
2219:                            scriptArrayIDs = new short[1];
2220:                            scriptArrayIDs[0] = scriptArrayID;
2221:                        } else {
2222:                            scriptArrayIDs = sequences.get(elcID);
2223:                            if (scriptArrayIDs == null) {
2224:                                scriptArrayIDs = new short[5];
2225:                            }
2226:                            Integer fid = logicalFontIDs.get(key);
2227:                            if (fid == null) {
2228:                                if (logger != null) {
2229:                                    logger
2230:                                            .config("Unrecognizable logicfont name "
2231:                                                    + key);
2232:                                }
2233:                                return;
2234:                            }
2235:                            //System.out.println("sequence." + key + "/" + id);
2236:                            scriptArrayIDs[fid.intValue()] = scriptArrayID;
2237:                        }
2238:                        sequences.put(elcID, scriptArrayIDs);
2239:                        if (hasDefault) {
2240:                            alphabeticSuffix.put(elcID, getStringID("default"));
2241:                        } else if (has1252) {
2242:                            alphabeticSuffix.put(elcID, getStringID("1252"));
2243:                        }
2244:                    } else if (key.startsWith("allfonts.")) {
2245:                        key = key.substring(9);
2246:                        if (key.endsWith(".motif")) {
2247:                            key = key.substring(0, key.length() - 6);
2248:                            //System.out.println("motif: all." + key + "=" + value);
2249:                            scriptAllfontsMotif.put(getID(scriptIDs, key),
2250:                                    getID(componentFontNameIDs, value));
2251:                        } else {
2252:                            scriptAllfonts.put(getID(scriptIDs, key), getID(
2253:                                    componentFontNameIDs, value));
2254:                        }
2255:                    } else if (key.startsWith("awtfontpath.")) {
2256:                        key = key.substring(12);
2257:                        //System.out.println("scriptID=" + getID(scriptIDs, key) + "/" + key);
2258:                        awtfontpaths.put(getID(scriptIDs, key),
2259:                                getStringID(value));
2260:                    } else if ("version".equals(key)) {
2261:                        version = value;
2262:                    } else if ("appendedfontpath".equals(key)) {
2263:                        appendedfontpath = value;
2264:                    } else if (key.startsWith("proportional.")) {
2265:                        key = key.substring(13).replace('_', ' ');
2266:                        //System.out.println(key + "=" + value);
2267:                        proportionals.put(getID(componentFontNameIDs, key),
2268:                                getID(componentFontNameIDs, value));
2269:                    } else {
2270:                        //"name.style.script(.motif)", we dont care anything else
2271:                        int dot1, dot2;
2272:                        boolean isMotif = false;
2273:
2274:                        dot1 = key.indexOf('.');
2275:                        if (dot1 == -1) {
2276:                            if (logger != null) {
2277:                                logger.config("Failed parsing " + key
2278:                                        + " property of font configuration.");
2279:
2280:                            }
2281:                            return;
2282:                        }
2283:                        dot2 = key.indexOf('.', dot1 + 1);
2284:                        if (dot2 == -1) {
2285:                            if (logger != null) {
2286:                                logger.config("Failed parsing " + key
2287:                                        + " property of font configuration.");
2288:
2289:                            }
2290:                            return;
2291:                        }
2292:                        if (key.endsWith(".motif")) {
2293:                            key = key.substring(0, key.length() - 6);
2294:                            isMotif = true;
2295:                            //System.out.println("motif: " + key + "=" + value);
2296:                        }
2297:                        Integer nameID = logicalFontIDs.get(key.substring(0,
2298:                                dot1));
2299:                        Integer styleID = fontStyleIDs.get(key.substring(
2300:                                dot1 + 1, dot2));
2301:                        Short scriptID = getID(scriptIDs, key
2302:                                .substring(dot2 + 1));
2303:                        if (nameID == null || styleID == null) {
2304:                            if (logger != null) {
2305:                                logger
2306:                                        .config("unrecognizable logicfont name/style at "
2307:                                                + key);
2308:                            }
2309:                            return;
2310:                        }
2311:                        Short[] pnids;
2312:                        if (isMotif) {
2313:                            pnids = scriptFontsMotif.get(scriptID);
2314:                        } else {
2315:                            pnids = scriptFonts.get(scriptID);
2316:                        }
2317:                        if (pnids == null) {
2318:                            pnids = new Short[20];
2319:                        }
2320:                        pnids[nameID.intValue() * NUM_STYLES
2321:                                + styleID.intValue()] = getID(
2322:                                componentFontNameIDs, value);
2323:                        /*
2324:                        System.out.println("key=" + key + "/<" + nameID + "><" + styleID 
2325:                             + "><" + scriptID + ">=" + value 
2326:                             + "/" + getID(componentFontNameIDs, value));
2327:                         */
2328:                        if (isMotif) {
2329:                            scriptFontsMotif.put(scriptID, pnids);
2330:                        } else {
2331:                            scriptFonts.put(scriptID, pnids);
2332:                        }
2333:                    }
2334:                }
2335:            }
2336:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.