int[] exclusionRanges = new int[numExclusionRanges]; int[] exclusionRangeLimits = new int[exclusions.length]; int exclusionRangeIndex = 0; int exclusionRangeLimitIndex = 0; for (int i = 0; i < exclusions.length; i++) { int[] componentRanges = exclusions[i]; for (int j = 0; j < componentRanges.length; ) { int value = componentRanges[j]; exclusionRanges[exclusionRangeIndex++] = componentRanges[j++]; exclusionRanges[exclusionRangeIndex++] = componentRanges[j++]; } exclusionRangeLimits[i] = exclusionRangeIndex; } // other info is per style for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) { int maxComponentFontCount = compFontNameIDs[fontIndex][styleIndex].length; boolean sawDefaultFontFile = false; // fall back fonts listed in the lib/fonts/fallback directory if (installedFallbackFontFiles != null) { maxComponentFontCount += installedFallbackFontFiles.length; } String faceName = fontName + "." + styleNames[styleIndex]; // determine face names and file names of component fonts String[] componentFaceNames = new String[maxComponentFontCount]; String[] componentFileNames = new String[maxComponentFontCount]; int index; for (index = 0; index < compFontNameIDs[fontIndex][styleIndex].length; index++) { short fontNameID = compFontNameIDs[fontIndex][styleIndex][index]; short fileNameID = getComponentFileID(fontNameID); componentFaceNames[index] = getFaceNameFromComponentFontName(getComponentFontName(fontNameID)); componentFileNames[index] = mapFileName(getComponentFileName(fileNameID)); if (componentFileNames[index] == null || needToSearchForFile(componentFileNames[index])) { componentFileNames[index] = getFileNameFromComponentFontName(getComponentFontName(fontNameID)); } if (!sawDefaultFontFile && defaultFontFile.equals(componentFileNames[index])) { sawDefaultFontFile = true; } /* System.out.println(publicFontNames[fontIndex] + "." + styleNames[styleIndex] + "." + getString(table_scriptIDs[coreScripts[index]]) + "=" + componentFileNames[index]); */ } //"Lucida Sans Regular" is not in the list, we add it here if (!sawDefaultFontFile) { int len = 0; if (installedFallbackFontFiles != null) { len = installedFallbackFontFiles.length; } if (index + len == maxComponentFontCount) { String[] newComponentFaceNames = new String[maxComponentFontCount + 1]; System.arraycopy(componentFaceNames, 0, newComponentFaceNames, 0, index); componentFaceNames = newComponentFaceNames; String[] newComponentFileNames = new String[maxComponentFontCount + 1]; System.arraycopy(componentFileNames, 0, newComponentFileNames, 0, index); componentFileNames = newComponentFileNames; } componentFaceNames[index] = defaultFontFaceName; componentFileNames[index] = defaultFontFile; index++; } if (installedFallbackFontFiles != null) { for (int ifb=0; ifb<installedFallbackFontFiles.length; ifb++) { componentFaceNames[index] = null; componentFileNames[index] = installedFallbackFontFiles[ifb]; index++; } } if (index < maxComponentFontCount) { String[] newComponentFaceNames = new String[index]; System.arraycopy(componentFaceNames, 0, newComponentFaceNames, 0, index); componentFaceNames = newComponentFaceNames; String[] newComponentFileNames = new String[index]; System.arraycopy(componentFileNames, 0, newComponentFileNames, 0, index); componentFileNames = newComponentFileNames; } // exclusion range limit array length must match component face name // array length - native code relies on this int[] clippedExclusionRangeLimits = exclusionRangeLimits; if (index != clippedExclusionRangeLimits.length) { int len = exclusionRangeLimits.length; clippedExclusionRangeLimits = new int[index]; System.arraycopy(exclusionRangeLimits, 0, clippedExclusionRangeLimits, 0, len); //padding for various fallback fonts for (int i = len; i < index; i++) { clippedExclusionRangeLimits[i] = exclusionRanges.length; } } /* System.out.println(faceName + ":"); for (int i = 0; i < componentFileNames.length; i++) { System.out.println(" " + componentFaceNames[i] + " -> " + componentFileNames[i]); } */ result[fontIndex * NUM_STYLES + styleIndex] = new CompositeFontDescriptor( faceName, compCoreNum[fontIndex], componentFaceNames, componentFileNames, exclusionRanges, clippedExclusionRangeLimits); } } return result; } protected abstract String getFaceNameFromComponentFontName(String componentFontName); protected abstract String getFileNameFromComponentFontName(String componentFontName); /* public class 2dFont { public String platformName; public String fontfileName; } private 2dFont [] componentFonts = null; */ /* Used on Linux to test if a file referenced in a font configuration * file exists in the location that is expected. If it does, no need * to search for it. If it doesn't then unless its a fallback font, * return that expensive code should be invoked to search for the font. */ HashMap<String, Boolean> existsMap; public boolean needToSearchForFile(String fileName) { if (!FontUtilities.isLinux) { return false; } else if (existsMap == null) { existsMap = new HashMap<String, Boolean>(); } Boolean exists = existsMap.get(fileName); if (exists == null) { /* call getNumberCoreFonts() to ensure these are initialised, and * if this file isn't for a core component, ie, is a for a fallback * font which very typically isn't available, then can't afford * to take the start-up penalty to search for it. */ getNumberCoreFonts(); if (!coreFontFileNames.contains(fileName)) { exists = Boolean.TRUE; } else { exists = Boolean.valueOf((new File(fileName)).exists()); existsMap.put(fileName, exists); if (FontUtilities.debugFonts() && exists == Boolean.FALSE) { logger.warning("Couldn't locate font file " + fileName); } } } return exists == Boolean.FALSE; } private int numCoreFonts = -1; private String[] componentFonts = null; HashMap <String, String> filenamesMap = new HashMap<String, String>(); HashSet <String> coreFontFileNames = new HashSet<String>(); /* Return the number of core fonts. Note this isn't thread safe but * a calling thread can call this and getPlatformFontNames() in either * order. */ public int getNumberCoreFonts() { if (numCoreFonts == -1) { numCoreFonts = coreFontNameIDs.size(); Short[] emptyShortArray = new Short[0]; Short[] core = coreFontNameIDs.toArray(emptyShortArray); Short[] fallback = fallbackFontNameIDs.toArray(emptyShortArray); int numFallbackFonts = 0; int i; for (i = 0; i < fallback.length; i++) { if (coreFontNameIDs.contains(fallback[i])) { fallback[i] = null; continue; } numFallbackFonts++; } componentFonts = new String[numCoreFonts + numFallbackFonts]; String filename = null; for (i = 0; i < core.length; i++) { short fontid = core[i]; short fileid = getComponentFileID(fontid); componentFonts[i] = getComponentFontName(fontid); String compFileName = getComponentFileName(fileid); if (compFileName != null) { coreFontFileNames.add(compFileName); } filenamesMap.put(componentFonts[i], mapFileName(compFileName)); } for (int j = 0; j < fallback.length; j++) { if (fallback[j] != null) { short fontid = fallback[j]; short fileid = getComponentFileID(fontid); componentFonts[i] = getComponentFontName(fontid); filenamesMap.put(componentFonts[i], mapFileName(getComponentFileName(fileid))); i++; } } } return numCoreFonts; } /* Return all platform font names used by this font configuration. * The first getNumberCoreFonts() entries are guaranteed to be the * core fonts - ie no fall back only fonts. */ public String[] getPlatformFontNames() { if (numCoreFonts == -1) { getNumberCoreFonts(); } return componentFonts; } /** * Returns a file name for the physical font represented by this platform font name, * if the font configuration has such information available, or null if the * information is unavailable. The file name returned is just a hint; a null return * value doesn't necessarily mean that the font is unavailable, nor does a non-null * return value guarantee that the file exists and contains the physical font. * The file name can be an absolute or a relative path name. */ public String getFileNameFromPlatformName(String platformName) { // get2DCompositeFontInfo // -> getFileNameFromComponentfontName() (W/M) // -> getFileNameFromPlatformName() // it's a waste of time on Win32, but I have to give X11 a chance to // call getFileNameFromXLFD() return filenamesMap.get(platformName); } /** * Returns a configuration specific path to be appended to the font * search path. */ public String getExtraFontPath() { return getString(head[INDEX_appendedfontpath]); } public String getVersion() { return getString(head[INDEX_version]); } /* subclass support */ protected static FontConfiguration getFontConfiguration() { return fontConfig; } protected void setFontConfiguration() { fontConfig = this; /* static initialization */ } ////////////////////////////////////////////////////////////////////// // FontConfig data tables and the index constants in binary file // ////////////////////////////////////////////////////////////////////// /* The binary font configuration file begins with a short[] "head", which * contains the offsets to the starts of the individual data table which * immediately follow. Teh current implemention includes the tables shown * below. * * (00) table_scriptIDs :stringIDs of all defined CharacterSubsetNames * (01) table_scriptFonts :scriptID x fontIndex x styleIndex-> * PlatformFontNameID mapping. Each scriptID might * have 1 or 20 entries depends on if it is defined * via a "allfonts.CharacterSubsetname" or a list of * "LogicalFontName.StyleName.CharacterSubsetName" * entries, positive entry means it's a "allfonts" * entry, a negative value means this is a offset to * a NUM_FONTS x NUM_STYLES subtable. * (02) table_elcIDs :stringIDs of all defined ELC names, string * "NULL.NULL.NULL" is used for "default" * (03) table_sequences :elcID x logicalFont -> scriptIDs table defined * by "sequence.allfonts/LogicalFontName.ELC" in * font configuration file, each "elcID" has * NUM_FONTS (5) entries in this table. * (04) table_fontfileNameIDs * :stringIDs of all defined font file names * (05) table_componentFontNameIDs * :stringIDs of all defined PlatformFontNames * (06) table_filenames :platformFontNamesID->fontfileNameID mapping * table, the index is the platformFontNamesID. * (07) table_awtfontpaths :CharacterSubsetNames->awtfontpaths mapping table, * the index is the CharacterSubsetName's stringID * and content is the stringID of awtfontpath. * (08) table_exclusions :scriptID -> exclusionRanges mapping table, * the index is the scriptID and the content is a id of an exclusionRanges int[]. * (09) table_proportionals:list of pairs of PlatformFontNameIDs, stores * the replacement info defined by "proportional" * keyword. * (10) table_scriptFontsMotif * :same as (01) except this table stores the * info defined with ".motif" keyword * (11) table_alphabeticSuffix * :elcID -> stringID of alphabetic/XXXX entries * (12) table_stringIDs :The index of this table is the string ID, the * content is the "start index" of this string in * stringTable, use the start index of next entry * as the "end index". * (13) table_stringTable :The real storage of all character strings defined * /used this font configuration, need a pair of * "start" and "end" indices to access. * (14) reserved * (15) table_fallbackScripts * :stringIDs of fallback CharacterSubsetnames, stored * in the order of they are defined in sequence.fallback. * (16) table_appendedfontpath * :stringtID of the "appendedfontpath" defined. * (17) table_version :stringID of the version number of this fontconfig file. */ private static final int HEAD_LENGTH = 20; private static final int INDEX_scriptIDs = 0; private static final int INDEX_scriptFonts = 1; private static final int INDEX_elcIDs = 2; private static final int INDEX_sequences = 3; private static final int INDEX_fontfileNameIDs = 4; private static final int INDEX_componentFontNameIDs = 5; private static final int INDEX_filenames = 6; private static final int INDEX_awtfontpaths = 7; private static final int INDEX_exclusions = 8; private static final int INDEX_proportionals = 9; private static final int INDEX_scriptFontsMotif = 10; private static final int INDEX_alphabeticSuffix = 11; private static final int INDEX_stringIDs = 12; private static final int INDEX_stringTable = 13; private static final int INDEX_TABLEEND = 14; private static final int INDEX_fallbackScripts = 15; private static final int INDEX_appendedfontpath = 16; private static final int INDEX_version = 17; private static short[] head; private static short[] table_scriptIDs; private static short[] table_scriptFonts; private static short[] table_elcIDs; private static short[] table_sequences; private static short[] table_fontfileNameIDs; private static short[] table_componentFontNameIDs; private static short[] table_filenames; protected static short[] table_awtfontpaths; private static short[] table_exclusions; private static short[] table_proportionals; private static short[] table_scriptFontsMotif; private static short[] table_alphabeticSuffix; private static short[] table_stringIDs; private static char[] table_stringTable; /** * Checks consistencies of complied fontconfig data. This method * is called only at the build-time from * build.tools.compilefontconfig.CompileFontConfig. */ private static void sanityCheck() { int errors = 0; //This method will only be called during build time, do we //need do PrivilegedAction? String osName = (String)java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { return System.getProperty("os.name"); } }); //componentFontNameID starts from "1" for (int ii = 1; ii < table_filenames.length; ii++) { if (table_filenames[ii] == -1) { // The corresponding finename entry for a component // font name is mandatory on Windows, but it's // optional on Solaris and Linux. if (osName.contains("Windows")) { System.err.println("\n Error: <filename." + getString(table_componentFontNameIDs[ii]) + "> entry is missing!!!"); errors++; } else { if (verbose && !isEmpty(table_filenames)) { System.err.println("\n Note: 'filename' entry is undefined for \"" + getString(table_componentFontNameIDs[ii]) + "\""); } } } } for (int ii = 0; ii < table_scriptIDs.length; ii++) { short fid = table_scriptFonts[ii]; if (fid == 0) { System.out.println("\n Error: <allfonts." + getString(table_scriptIDs[ii]) + "> entry is missing!!!"); errors++; continue; } else if (fid < 0) { fid = (short)-fid; for (int iii = 0; iii < NUM_FONTS; iii++) { for (int iij = 0; iij < NUM_STYLES; iij++) { int jj = iii * NUM_STYLES + iij; short ffid = table_scriptFonts[fid + jj]; if (ffid == 0) { System.err.println("\n Error: <" + getFontName(iii) + "." + getStyleName(iij) + "." + getString(table_scriptIDs[ii]) + "> entry is missing!!!"); errors++; } } } } } if ("SunOS".equals(osName)) { for (int ii = 0; ii < table_awtfontpaths.length; ii++) { if (table_awtfontpaths[ii] == 0) { String script = getString(table_scriptIDs[ii]); if (script.contains("lucida") || script.contains("dingbats") || script.contains("symbol")) { continue; } System.err.println("\nError: " + "<awtfontpath." + script + "> entry is missing!!!"); errors++; } } } if (errors != 0) { System.err.println("!!THERE ARE " + errors + " ERROR(S) IN " + "THE FONTCONFIG FILE, PLEASE CHECK ITS CONTENT!!\n"); System.exit(1); } } private static boolean isEmpty(short[] a) { for (short s : a) { if (s != -1) { return false; } } return true; } //dump the fontconfig data tables private static void dump() { System.out.println("\n----Head Table------------"); for (int ii = 0; ii < HEAD_LENGTH; ii++) { System.out.println(" " + ii + " : " + head[ii]); } System.out.println("\n----scriptIDs-------------"); printTable(table_scriptIDs, 0); System.out.println("\n----scriptFonts----------------"); for (int ii = 0; ii < table_scriptIDs.length; ii++) { short fid = table_scriptFonts[ii]; if (fid >= 0) { System.out.println(" allfonts." + getString(table_scriptIDs[ii]) + "=" + getString(table_componentFontNameIDs[fid])); } } for (int ii = 0; ii < table_scriptIDs.length; ii++) { short fid = table_scriptFonts[ii]; if (fid < 0) { fid = (short)-fid; for (int iii = 0; iii < NUM_FONTS; iii++) { for (int iij = 0; iij < NUM_STYLES; iij++) { int jj = iii * NUM_STYLES + iij; short ffid = table_scriptFonts[fid + jj]; System.out.println(" " + getFontName(iii) + "." + getStyleName(iij) + "." + getString(table_scriptIDs[ii]) + "=" + getString(table_componentFontNameIDs[ffid])); } } } } System.out.println("\n----elcIDs----------------"); printTable(table_elcIDs, 0); System.out.println("\n----sequences-------------"); for (int ii = 0; ii< table_elcIDs.length; ii++) { System.out.println(" " + ii + "/" + getString((short)table_elcIDs[ii])); short[] ss = getShortArray(table_sequences[ii * NUM_FONTS + 0]); for (int jj = 0; jj < ss.length; jj++) { System.out.println(" " + getString((short)table_scriptIDs[ss[jj]])); } } System.out.println("\n----fontfileNameIDs-------"); printTable(table_fontfileNameIDs, 0); Lines 1001–1500 of 2272. Previous lines Load more
int[] exclusionRanges = new int[numExclusionRanges]; int[] exclusionRangeLimits = new int[exclusions.length]; int exclusionRangeIndex = 0; int exclusionRangeLimitIndex = 0; for (int i = 0; i < exclusions.length; i++) { int[] componentRanges = exclusions[i]; for (int j = 0; j < componentRanges.length; ) { int value = componentRanges[j]; exclusionRanges[exclusionRangeIndex++] = componentRanges[j++]; exclusionRanges[exclusionRangeIndex++] = componentRanges[j++]; } exclusionRangeLimits[i] = exclusionRangeIndex; } // other info is per style for (int styleIndex = 0; styleIndex < NUM_STYLES; styleIndex++) { int maxComponentFontCount = compFontNameIDs[fontIndex][styleIndex].length; boolean sawDefaultFontFile = false; // fall back fonts listed in the lib/fonts/fallback directory if (installedFallbackFontFiles != null) { maxComponentFontCount += installedFallbackFontFiles.length; } String faceName = fontName + "." + styleNames[styleIndex]; // determine face names and file names of component fonts String[] componentFaceNames = new String[maxComponentFontCount]; String[] componentFileNames = new String[maxComponentFontCount]; int index; for (index = 0; index < compFontNameIDs[fontIndex][styleIndex].length; index++) { short fontNameID = compFontNameIDs[fontIndex][styleIndex][index]; short fileNameID = getComponentFileID(fontNameID); componentFaceNames[index] = getFaceNameFromComponentFontName(getComponentFontName(fontNameID)); componentFileNames[index] = mapFileName(getComponentFileName(fileNameID)); if (componentFileNames[index] == null || needToSearchForFile(componentFileNames[index])) { componentFileNames[index] = getFileNameFromComponentFontName(getComponentFontName(fontNameID)); } if (!sawDefaultFontFile && defaultFontFile.equals(componentFileNames[index])) { sawDefaultFontFile = true; } /* System.out.println(publicFontNames[fontIndex] + "." + styleNames[styleIndex] + "." + getString(table_scriptIDs[coreScripts[index]]) + "=" + componentFileNames[index]); */ } //"Lucida Sans Regular" is not in the list, we add it here if (!sawDefaultFontFile) { int len = 0; if (installedFallbackFontFiles != null) { len = installedFallbackFontFiles.length; } if (index + len == maxComponentFontCount) { String[] newComponentFaceNames = new String[maxComponentFontCount + 1]; System.arraycopy(componentFaceNames, 0, newComponentFaceNames, 0, index); componentFaceNames = newComponentFaceNames; String[] newComponentFileNames = new String[maxComponentFontCount + 1]; System.arraycopy(componentFileNames, 0, newComponentFileNames, 0, index); componentFileNames = newComponentFileNames; } componentFaceNames[index] = defaultFontFaceName; componentFileNames[index] = defaultFontFile; index++; } if (installedFallbackFontFiles != null) { for (int ifb=0; ifb<installedFallbackFontFiles.length; ifb++) { componentFaceNames[index] = null; componentFileNames[index] = installedFallbackFontFiles[ifb]; index++; } } if (index < maxComponentFontCount) { String[] newComponentFaceNames = new String[index]; System.arraycopy(componentFaceNames, 0, newComponentFaceNames, 0, index); componentFaceNames = newComponentFaceNames; String[] newComponentFileNames = new String[index]; System.arraycopy(componentFileNames, 0, newComponentFileNames, 0, index); componentFileNames = newComponentFileNames; } // exclusion range limit array length must match component face name // array length - native code relies on this int[] clippedExclusionRangeLimits = exclusionRangeLimits; if (index != clippedExclusionRangeLimits.length) { int len = exclusionRangeLimits.length; clippedExclusionRangeLimits = new int[index]; System.arraycopy(exclusionRangeLimits, 0, clippedExclusionRangeLimits, 0, len); //padding for various fallback fonts for (int i = len; i < index; i++) { clippedExclusionRangeLimits[i] = exclusionRanges.length; } } /* System.out.println(faceName + ":"); for (int i = 0; i < componentFileNames.length; i++) { System.out.println(" " + componentFaceNames[i] + " -> " + componentFileNames[i]); } */ result[fontIndex * NUM_STYLES + styleIndex] = new CompositeFontDescriptor( faceName, compCoreNum[fontIndex], componentFaceNames, componentFileNames, exclusionRanges, clippedExclusionRangeLimits); } } return result; } protected abstract String getFaceNameFromComponentFontName(String componentFontName); protected abstract String getFileNameFromComponentFontName(String componentFontName); /* public class 2dFont { public String platformName; public String fontfileName; } private 2dFont [] componentFonts = null; */ /* Used on Linux to test if a file referenced in a font configuration * file exists in the location that is expected. If it does, no need * to search for it. If it doesn't then unless its a fallback font, * return that expensive code should be invoked to search for the font. */ HashMap<String, Boolean> existsMap; public boolean needToSearchForFile(String fileName) { if (!FontUtilities.isLinux) { return false; } else if (existsMap == null) { existsMap = new HashMap<String, Boolean>(); } Boolean exists = existsMap.get(fileName); if (exists == null) { /* call getNumberCoreFonts() to ensure these are initialised, and * if this file isn't for a core component, ie, is a for a fallback * font which very typically isn't available, then can't afford * to take the start-up penalty to search for it. */ getNumberCoreFonts(); if (!coreFontFileNames.contains(fileName)) { exists = Boolean.TRUE; } else { exists = Boolean.valueOf((new File(fileName)).exists()); existsMap.put(fileName, exists); if (FontUtilities.debugFonts() && exists == Boolean.FALSE) { logger.warning("Couldn't locate font file " + fileName); } } } return exists == Boolean.FALSE; } private int numCoreFonts = -1; private String[] componentFonts = null; HashMap <String, String> filenamesMap = new HashMap<String, String>(); HashSet <String> coreFontFileNames = new HashSet<String>(); /* Return the number of core fonts. Note this isn't thread safe but * a calling thread can call this and getPlatformFontNames() in either * order. */ public int getNumberCoreFonts() { if (numCoreFonts == -1) { numCoreFonts = coreFontNameIDs.size(); Short[] emptyShortArray = new Short[0]; Short[] core = coreFontNameIDs.toArray(emptyShortArray); Short[] fallback = fallbackFontNameIDs.toArray(emptyShortArray); int numFallbackFonts = 0; int i; for (i = 0; i < fallback.length; i++) { if (coreFontNameIDs.contains(fallback[i])) { fallback[i] = null; continue; } numFallbackFonts++; } componentFonts = new String[numCoreFonts + numFallbackFonts]; String filename = null; for (i = 0; i < core.length; i++) { short fontid = core[i]; short fileid = getComponentFileID(fontid); componentFonts[i] = getComponentFontName(fontid); String compFileName = getComponentFileName(fileid); if (compFileName != null) { coreFontFileNames.add(compFileName); } filenamesMap.put(componentFonts[i], mapFileName(compFileName)); } for (int j = 0; j < fallback.length; j++) { if (fallback[j] != null) { short fontid = fallback[j]; short fileid = getComponentFileID(fontid); componentFonts[i] = getComponentFontName(fontid); filenamesMap.put(componentFonts[i], mapFileName(getComponentFileName(fileid))); i++; } } } return numCoreFonts; } /* Return all platform font names used by this font configuration. * The first getNumberCoreFonts() entries are guaranteed to be the * core fonts - ie no fall back only fonts. */ public String[] getPlatformFontNames() { if (numCoreFonts == -1) { getNumberCoreFonts(); } return componentFonts; } /** * Returns a file name for the physical font represented by this platform font name, * if the font configuration has such information available, or null if the * information is unavailable. The file name returned is just a hint; a null return * value doesn't necessarily mean that the font is unavailable, nor does a non-null * return value guarantee that the file exists and contains the physical font. * The file name can be an absolute or a relative path name. */ public String getFileNameFromPlatformName(String platformName) { // get2DCompositeFontInfo // -> getFileNameFromComponentfontName() (W/M) // -> getFileNameFromPlatformName() // it's a waste of time on Win32, but I have to give X11 a chance to // call getFileNameFromXLFD() return filenamesMap.get(platformName); } /** * Returns a configuration specific path to be appended to the font * search path. */ public String getExtraFontPath() { return getString(head[INDEX_appendedfontpath]); } public String getVersion() { return getString(head[INDEX_version]); } /* subclass support */ protected static FontConfiguration getFontConfiguration() { return fontConfig; } protected void setFontConfiguration() { fontConfig = this; /* static initialization */ } ////////////////////////////////////////////////////////////////////// // FontConfig data tables and the index constants in binary file // ////////////////////////////////////////////////////////////////////// /* The binary font configuration file begins with a short[] "head", which * contains the offsets to the starts of the individual data table which * immediately follow. Teh current implemention includes the tables shown * below. * * (00) table_scriptIDs :stringIDs of all defined CharacterSubsetNames * (01) table_scriptFonts :scriptID x fontIndex x styleIndex-> * PlatformFontNameID mapping. Each scriptID might * have 1 or 20 entries depends on if it is defined * via a "allfonts.CharacterSubsetname" or a list of * "LogicalFontName.StyleName.CharacterSubsetName" * entries, positive entry means it's a "allfonts" * entry, a negative value means this is a offset to * a NUM_FONTS x NUM_STYLES subtable. * (02) table_elcIDs :stringIDs of all defined ELC names, string * "NULL.NULL.NULL" is used for "default" * (03) table_sequences :elcID x logicalFont -> scriptIDs table defined * by "sequence.allfonts/LogicalFontName.ELC" in * font configuration file, each "elcID" has * NUM_FONTS (5) entries in this table. * (04) table_fontfileNameIDs * :stringIDs of all defined font file names * (05) table_componentFontNameIDs * :stringIDs of all defined PlatformFontNames * (06) table_filenames :platformFontNamesID->fontfileNameID mapping * table, the index is the platformFontNamesID. * (07) table_awtfontpaths :CharacterSubsetNames->awtfontpaths mapping table, * the index is the CharacterSubsetName's stringID * and content is the stringID of awtfontpath. * (08) table_exclusions :scriptID -> exclusionRanges mapping table, * the index is the scriptID and the content is a id of an exclusionRanges int[]. * (09) table_proportionals:list of pairs of PlatformFontNameIDs, stores * the replacement info defined by "proportional" * keyword. * (10) table_scriptFontsMotif * :same as (01) except this table stores the * info defined with ".motif" keyword * (11) table_alphabeticSuffix * :elcID -> stringID of alphabetic/XXXX entries * (12) table_stringIDs :The index of this table is the string ID, the * content is the "start index" of this string in * stringTable, use the start index of next entry * as the "end index". * (13) table_stringTable :The real storage of all character strings defined * /used this font configuration, need a pair of * "start" and "end" indices to access. * (14) reserved * (15) table_fallbackScripts * :stringIDs of fallback CharacterSubsetnames, stored * in the order of they are defined in sequence.fallback. * (16) table_appendedfontpath * :stringtID of the "appendedfontpath" defined. * (17) table_version :stringID of the version number of this fontconfig file. */ private static final int HEAD_LENGTH = 20; private static final int INDEX_scriptIDs = 0; private static final int INDEX_scriptFonts = 1; private static final int INDEX_elcIDs = 2; private static final int INDEX_sequences = 3; private static final int INDEX_fontfileNameIDs = 4; private static final int INDEX_componentFontNameIDs = 5; private static final int INDEX_filenames = 6; private static final int INDEX_awtfontpaths = 7; private static final int INDEX_exclusions = 8; private static final int INDEX_proportionals = 9; private static final int INDEX_scriptFontsMotif = 10; private static final int INDEX_alphabeticSuffix = 11; private static final int INDEX_stringIDs = 12; private static final int INDEX_stringTable = 13; private static final int INDEX_TABLEEND = 14; private static final int INDEX_fallbackScripts = 15; private static final int INDEX_appendedfontpath = 16; private static final int INDEX_version = 17; private static short[] head; private static short[] table_scriptIDs; private static short[] table_scriptFonts; private static short[] table_elcIDs; private static short[] table_sequences; private static short[] table_fontfileNameIDs; private static short[] table_componentFontNameIDs; private static short[] table_filenames; protected static short[] table_awtfontpaths; private static short[] table_exclusions; private static short[] table_proportionals; private static short[] table_scriptFontsMotif; private static short[] table_alphabeticSuffix; private static short[] table_stringIDs; private static char[] table_stringTable; /** * Checks consistencies of complied fontconfig data. This method * is called only at the build-time from * build.tools.compilefontconfig.CompileFontConfig. */ private static void sanityCheck() { int errors = 0; //This method will only be called during build time, do we //need do PrivilegedAction? String osName = (String)java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { return System.getProperty("os.name"); } }); //componentFontNameID starts from "1" for (int ii = 1; ii < table_filenames.length; ii++) { if (table_filenames[ii] == -1) { // The corresponding finename entry for a component // font name is mandatory on Windows, but it's // optional on Solaris and Linux. if (osName.contains("Windows")) { System.err.println("\n Error: <filename." + getString(table_componentFontNameIDs[ii]) + "> entry is missing!!!"); errors++; } else { if (verbose && !isEmpty(table_filenames)) { System.err.println("\n Note: 'filename' entry is undefined for \"" + getString(table_componentFontNameIDs[ii]) + "\""); } } } } for (int ii = 0; ii < table_scriptIDs.length; ii++) { short fid = table_scriptFonts[ii]; if (fid == 0) { System.out.println("\n Error: <allfonts." + getString(table_scriptIDs[ii]) + "> entry is missing!!!"); errors++; continue; } else if (fid < 0) { fid = (short)-fid; for (int iii = 0; iii < NUM_FONTS; iii++) { for (int iij = 0; iij < NUM_STYLES; iij++) { int jj = iii * NUM_STYLES + iij; short ffid = table_scriptFonts[fid + jj]; if (ffid == 0) { System.err.println("\n Error: <" + getFontName(iii) + "." + getStyleName(iij) + "." + getString(table_scriptIDs[ii]) + "> entry is missing!!!"); errors++; } } } } } if ("SunOS".equals(osName)) { for (int ii = 0; ii < table_awtfontpaths.length; ii++) { if (table_awtfontpaths[ii] == 0) { String script = getString(table_scriptIDs[ii]); if (script.contains("lucida") || script.contains("dingbats") || script.contains("symbol")) { continue; } System.err.println("\nError: " + "<awtfontpath." + script + "> entry is missing!!!"); errors++; } } } if (errors != 0) { System.err.println("!!THERE ARE " + errors + " ERROR(S) IN " + "THE FONTCONFIG FILE, PLEASE CHECK ITS CONTENT!!\n"); System.exit(1); } } private static boolean isEmpty(short[] a) { for (short s : a) { if (s != -1) { return false; } } return true; } //dump the fontconfig data tables private static void dump() { System.out.println("\n----Head Table------------"); for (int ii = 0; ii < HEAD_LENGTH; ii++) { System.out.println(" " + ii + " : " + head[ii]); } System.out.println("\n----scriptIDs-------------"); printTable(table_scriptIDs, 0); System.out.println("\n----scriptFonts----------------"); for (int ii = 0; ii < table_scriptIDs.length; ii++) { short fid = table_scriptFonts[ii]; if (fid >= 0) { System.out.println(" allfonts." + getString(table_scriptIDs[ii]) + "=" + getString(table_componentFontNameIDs[fid])); } } for (int ii = 0; ii < table_scriptIDs.length; ii++) { short fid = table_scriptFonts[ii]; if (fid < 0) { fid = (short)-fid; for (int iii = 0; iii < NUM_FONTS; iii++) { for (int iij = 0; iij < NUM_STYLES; iij++) { int jj = iii * NUM_STYLES + iij; short ffid = table_scriptFonts[fid + jj]; System.out.println(" " + getFontName(iii) + "." + getStyleName(iij) + "." + getString(table_scriptIDs[ii]) + "=" + getString(table_componentFontNameIDs[ffid])); } } } } System.out.println("\n----elcIDs----------------"); printTable(table_elcIDs, 0); System.out.println("\n----sequences-------------"); for (int ii = 0; ii< table_elcIDs.length; ii++) { System.out.println(" " + ii + "/" + getString((short)table_elcIDs[ii])); short[] ss = getShortArray(table_sequences[ii * NUM_FONTS + 0]); for (int jj = 0; jj < ss.length; jj++) { System.out.println(" " + getString((short)table_scriptIDs[ss[jj]])); } } System.out.println("\n----fontfileNameIDs-------"); printTable(table_fontfileNameIDs, 0);