System.out.println("\n----componentFontNameIDs--"); printTable(table_componentFontNameIDs, 1); System.out.println("\n----filenames-------------"); for (int ii = 0; ii < table_filenames.length; ii++) { if (table_filenames[ii] == -1) { System.out.println(" " + ii + " : null"); } else { System.out.println(" " + ii + " : " + getString(table_fontfileNameIDs[table_filenames[ii]])); } } System.out.println("\n----awtfontpaths---------"); for (int ii = 0; ii < table_awtfontpaths.length; ii++) { System.out.println(" " + getString(table_scriptIDs[ii]) + " : " + getString(table_awtfontpaths[ii])); } System.out.println("\n----proportionals--------"); for (int ii = 0; ii < table_proportionals.length; ii++) { System.out.println(" " + getString((short)table_componentFontNameIDs[table_proportionals[ii++]]) + " -> " + getString((short)table_componentFontNameIDs[table_proportionals[ii]])); } int i = 0; System.out.println("\n----alphabeticSuffix----"); while (i < table_alphabeticSuffix.length) { System.out.println(" " + getString(table_elcIDs[table_alphabeticSuffix[i++]]) + " -> " + getString(table_alphabeticSuffix[i++])); } System.out.println("\n----String Table---------"); System.out.println(" stringID: Num =" + table_stringIDs.length); System.out.println(" stringTable: Size=" + table_stringTable.length * 2); System.out.println("\n----fallbackScriptIDs---"); short[] fbsIDs = getShortArray(head[INDEX_fallbackScripts]); for (int ii = 0; ii < fbsIDs.length; ii++) { System.out.println(" " + getString(table_scriptIDs[fbsIDs[ii]])); } System.out.println("\n----appendedfontpath-----"); System.out.println(" " + getString(head[INDEX_appendedfontpath])); System.out.println("\n----Version--------------"); System.out.println(" " + getString(head[INDEX_version])); } ////////////////////////////////////////////////////////////////////// // Data table access methods // ////////////////////////////////////////////////////////////////////// /* Return the fontID of the platformFontName defined in this font config * by "LogicalFontName.StyleName.CharacterSubsetName" entry or * "allfonts.CharacterSubsetName" entry in properties format fc file. */ protected static short getComponentFontID(short scriptID, int fontIndex, int styleIndex) { short fid = table_scriptFonts[scriptID]; //System.out.println("fid=" + fid + "/ scriptID=" + scriptID + ", fi=" + fontIndex + ", si=" + styleIndex); if (fid >= 0) { //"allfonts" return fid; } else { return table_scriptFonts[-fid + fontIndex * NUM_STYLES + styleIndex]; } } /* Same as getCompoentFontID() except this method returns the fontID define by * "xxxx.motif" entry. */ protected static short getComponentFontIDMotif(short scriptID, int fontIndex, int styleIndex) { if (table_scriptFontsMotif.length == 0) { return 0; } short fid = table_scriptFontsMotif[scriptID]; if (fid >= 0) { //"allfonts" > 0 or "not defined" == 0 return fid; } else { return table_scriptFontsMotif[-fid + fontIndex * NUM_STYLES + styleIndex]; } } private static int[] getExclusionRanges(short scriptID) { short exID = table_exclusions[scriptID]; if (exID == 0) { return EMPTY_INT_ARRAY; } else { char[] exChar = getString(exID).toCharArray(); int[] exInt = new int[exChar.length / 2]; int i = 0; for (int j = 0; j < exInt.length; j++) { exInt[j] = (exChar[i++] << 16) + (exChar[i++] & 0xffff); } return exInt; } } private static boolean contains(short IDs[], short id, int limit) { for (int i = 0; i < limit; i++) { if (IDs[i] == id) { return true; } } return false; } /* Return the PlatformFontName from its fontID*/ protected static String getComponentFontName(short id) { if (id < 0) { return null; } return getString(table_componentFontNameIDs[id]); } private static String getComponentFileName(short id) { if (id < 0) { return null; } return getString(table_fontfileNameIDs[id]); } //componentFontID -> componentFileID private static short getComponentFileID(short nameID) { return table_filenames[nameID]; } private static String getScriptName(short scriptID) { return getString(table_scriptIDs[scriptID]); } private HashMap<String, Short> reorderScripts; protected short[] getCoreScripts(int fontIndex) { short elc = getInitELC(); /* System.out.println("getCoreScripts: elc=" + elc + ", fontIndex=" + fontIndex); short[] ss = getShortArray(table_sequences[elc * NUM_FONTS + fontIndex]); for (int i = 0; i < ss.length; i++) { System.out.println(" " + getString((short)table_scriptIDs[ss[i]])); } */ short[] scripts = getShortArray(table_sequences[elc * NUM_FONTS + fontIndex]); if (preferLocaleFonts) { if (reorderScripts == null) { reorderScripts = new HashMap<String, Short>(); } String[] ss = new String[scripts.length]; for (int i = 0; i < ss.length; i++) { ss[i] = getScriptName(scripts[i]); reorderScripts.put(ss[i], scripts[i]); } reorderSequenceForLocale(ss); for (int i = 0; i < ss.length; i++) { scripts[i] = reorderScripts.get(ss[i]); } } return scripts; } private static short[] getFallbackScripts() { return getShortArray(head[INDEX_fallbackScripts]); } private static void printTable(short[] list, int start) { for (int i = start; i < list.length; i++) { System.out.println(" " + i + " : " + getString(list[i])); } } private static short[] readShortTable(DataInputStream in, int len ) throws IOException { if (len == 0) { return EMPTY_SHORT_ARRAY; } short[] data = new short[len]; byte[] bb = new byte[len * 2]; in.read(bb); int i = 0,j = 0; while (i < len) { data[i++] = (short)(bb[j++] << 8 | (bb[j++] & 0xff)); } return data; } private static void writeShortTable(DataOutputStream out, short[] data) throws IOException { for (short val : data) { out.writeShort(val); } } private static short[] toList(HashMap<String, Short> map) { short[] list = new short[map.size()]; Arrays.fill(list, (short) -1); for (Entry<String, Short> entry : map.entrySet()) { list[entry.getValue()] = getStringID(entry.getKey()); } return list; } //runtime cache private static String[] stringCache; protected static String getString(short stringID) { if (stringID == 0) return null; /* if (loadingProperties) { return stringTable.substring(stringIDs[stringID], stringIDs[stringID+1]); } */ //sync if we want it to be MT-enabled if (stringCache[stringID] == null){ stringCache[stringID] = new String (table_stringTable, table_stringIDs[stringID], table_stringIDs[stringID+1] - table_stringIDs[stringID]); } return stringCache[stringID]; } private static short[] getShortArray(short shortArrayID) { String s = getString(shortArrayID); char[] cc = s.toCharArray(); short[] ss = new short[cc.length]; for (int i = 0; i < cc.length; i++) { ss[i] = (short)(cc[i] & 0xffff); } return ss; } private static short getStringID(String s) { if (s == null) { return (short)0; } short pos0 = (short)stringTable.length(); stringTable.append(s); short pos1 = (short)stringTable.length(); stringIDs[stringIDNum] = pos0; stringIDs[stringIDNum + 1] = pos1; stringIDNum++; if (stringIDNum + 1 >= stringIDs.length) { short[] tmp = new short[stringIDNum + 1000]; System.arraycopy(stringIDs, 0, tmp, 0, stringIDNum); stringIDs = tmp; } return (short)(stringIDNum - 1); } private static short getShortArrayID(short sa[]) { char[] cc = new char[sa.length]; for (int i = 0; i < sa.length; i ++) { cc[i] = (char)sa[i]; } String s = new String(cc); return getStringID(s); } //utility "empty" objects private static final int[] EMPTY_INT_ARRAY = new int[0]; private static final String[] EMPTY_STRING_ARRAY = new String[0]; private static final short[] EMPTY_SHORT_ARRAY = new short[0]; private static final String UNDEFINED_COMPONENT_FONT = "unknown"; ////////////////////////////////////////////////////////////////////////// //Convert the FontConfig data in Properties file to binary data tables // ////////////////////////////////////////////////////////////////////////// static class PropertiesHandler { public void load(InputStream in) throws IOException { initLogicalNameStyle(); initHashMaps(); FontProperties fp = new FontProperties(); fp.load(in); initBinaryTable(); } private void initBinaryTable() { //(0) head = new short[HEAD_LENGTH]; head[INDEX_scriptIDs] = (short)HEAD_LENGTH; table_scriptIDs = toList(scriptIDs); //(1)a: scriptAllfonts scriptID/allfonts -> componentFontNameID // b: scriptFonts scriptID -> componentFontNameID[20] //if we have a "allfonts.script" def, then we just put //the "-platformFontID" value in the slot, otherwise the slot //value is "offset" which "offset" is where 20 entries located //in the table attached. head[INDEX_scriptFonts] = (short)(head[INDEX_scriptIDs] + table_scriptIDs.length); int len = table_scriptIDs.length + scriptFonts.size() * 20; table_scriptFonts = new short[len]; for (Entry<Short, Short> entry : scriptAllfonts.entrySet()) { table_scriptFonts[entry.getKey().intValue()] = entry.getValue(); } int off = table_scriptIDs.length; for (Entry<Short, Short[]> entry : scriptFonts.entrySet()) { table_scriptFonts[entry.getKey().intValue()] = (short)-off; Short[] v = entry.getValue(); for (int i = 0; i < 20; i++) { if (v[i] != null) { table_scriptFonts[off++] = v[i]; } else { table_scriptFonts[off++] = 0; } } } //(2) head[INDEX_elcIDs] = (short)(head[INDEX_scriptFonts] + table_scriptFonts.length); table_elcIDs = toList(elcIDs); //(3) sequences elcID -> XXXX[1|5] -> scriptID[] head[INDEX_sequences] = (short)(head[INDEX_elcIDs] + table_elcIDs.length); table_sequences = new short[elcIDs.size() * NUM_FONTS]; for (Entry<Short, short[]> entry : sequences.entrySet()) { //table_sequences[entry.getKey().intValue()] = (short)-off; int k = entry.getKey().intValue(); short[] v = entry.getValue(); /* System.out.println("elc=" + k + "/" + getString((short)table_elcIDs[k])); short[] ss = getShortArray(v[0]); for (int i = 0; i < ss.length; i++) { System.out.println(" " + getString((short)table_scriptIDs[ss[i]])); } */ if (v.length == 1) { //the "allfonts" entries for (int i = 0; i < NUM_FONTS; i++) { table_sequences[k * NUM_FONTS + i] = v[0]; } } else { for (int i = 0; i < NUM_FONTS; i++) { table_sequences[k * NUM_FONTS + i] = v[i]; } } } //(4) head[INDEX_fontfileNameIDs] = (short)(head[INDEX_sequences] + table_sequences.length); table_fontfileNameIDs = toList(fontfileNameIDs); //(5) head[INDEX_componentFontNameIDs] = (short)(head[INDEX_fontfileNameIDs] + table_fontfileNameIDs.length); table_componentFontNameIDs = toList(componentFontNameIDs); //(6)componentFontNameID -> filenameID head[INDEX_filenames] = (short)(head[INDEX_componentFontNameIDs] + table_componentFontNameIDs.length); table_filenames = new short[table_componentFontNameIDs.length]; Arrays.fill(table_filenames, (short) -1); for (Entry<Short, Short> entry : filenames.entrySet()) { table_filenames[entry.getKey()] = entry.getValue(); } //(7)scriptID-> awtfontpath //the paths are stored as scriptID -> stringID in awtfontpahts head[INDEX_awtfontpaths] = (short)(head[INDEX_filenames] + table_filenames.length); table_awtfontpaths = new short[table_scriptIDs.length]; for (Entry<Short, Short> entry : awtfontpaths.entrySet()) { table_awtfontpaths[entry.getKey()] = entry.getValue(); } //(8)exclusions head[INDEX_exclusions] = (short)(head[INDEX_awtfontpaths] + table_awtfontpaths.length); table_exclusions = new short[scriptIDs.size()]; for (Entry<Short, int[]> entry : exclusions.entrySet()) { int[] exI = entry.getValue(); char[] exC = new char[exI.length * 2]; int j = 0; for (int i = 0; i < exI.length; i++) { exC[j++] = (char) (exI[i] >> 16); exC[j++] = (char) (exI[i] & 0xffff); } table_exclusions[entry.getKey()] = getStringID(new String (exC)); } //(9)proportionals head[INDEX_proportionals] = (short)(head[INDEX_exclusions] + table_exclusions.length); table_proportionals = new short[proportionals.size() * 2]; int j = 0; for (Entry<Short, Short> entry : proportionals.entrySet()) { table_proportionals[j++] = entry.getKey(); table_proportionals[j++] = entry.getValue(); } //(10) see (1) for info, the only difference is "xxx.motif" head[INDEX_scriptFontsMotif] = (short)(head[INDEX_proportionals] + table_proportionals.length); if (scriptAllfontsMotif.size() != 0 || scriptFontsMotif.size() != 0) { len = table_scriptIDs.length + scriptFontsMotif.size() * 20; table_scriptFontsMotif = new short[len]; for (Entry<Short, Short> entry : scriptAllfontsMotif.entrySet()) { table_scriptFontsMotif[entry.getKey().intValue()] = (short)entry.getValue(); } off = table_scriptIDs.length; for (Entry<Short, Short[]> entry : scriptFontsMotif.entrySet()) { table_scriptFontsMotif[entry.getKey().intValue()] = (short)-off; Short[] v = entry.getValue(); int i = 0; while (i < 20) { if (v[i] != null) { table_scriptFontsMotif[off++] = v[i]; } else { table_scriptFontsMotif[off++] = 0; } i++; } } } else { table_scriptFontsMotif = EMPTY_SHORT_ARRAY; } //(11)short[] alphabeticSuffix head[INDEX_alphabeticSuffix] = (short)(head[INDEX_scriptFontsMotif] + table_scriptFontsMotif.length); table_alphabeticSuffix = new short[alphabeticSuffix.size() * 2]; j = 0; for (Entry<Short, Short> entry : alphabeticSuffix.entrySet()) { table_alphabeticSuffix[j++] = entry.getKey(); table_alphabeticSuffix[j++] = entry.getValue(); } //(15)short[] fallbackScriptIDs; just put the ID in head head[INDEX_fallbackScripts] = getShortArrayID(fallbackScriptIDs); //(16)appendedfontpath head[INDEX_appendedfontpath] = getStringID(appendedfontpath); //(17)version head[INDEX_version] = getStringID(version); //(12)short[] StringIDs head[INDEX_stringIDs] = (short)(head[INDEX_alphabeticSuffix] + table_alphabeticSuffix.length); table_stringIDs = new short[stringIDNum + 1]; System.arraycopy(stringIDs, 0, table_stringIDs, 0, stringIDNum + 1); //(13)StringTable head[INDEX_stringTable] = (short)(head[INDEX_stringIDs] + stringIDNum + 1); table_stringTable = stringTable.toString().toCharArray(); //(14) head[INDEX_TABLEEND] = (short)(head[INDEX_stringTable] + stringTable.length()); //StringTable cache stringCache = new String[table_stringIDs.length]; } ////////////////////////////////////////////// private HashMap<String, Short> scriptIDs; //elc -> Encoding.Language.Country private HashMap<String, Short> elcIDs; //componentFontNameID starts from "1", "0" reserves for "undefined" private HashMap<String, Short> componentFontNameIDs; private HashMap<String, Short> fontfileNameIDs; private HashMap<String, Integer> logicalFontIDs; private HashMap<String, Integer> fontStyleIDs; //componentFontNameID -> fontfileNameID private HashMap<Short, Short> filenames; //elcID -> allfonts/logicalFont -> scriptID list //(1)if we have a "allfonts", then the length of the // value array is "1", otherwise it's 5, each font // must have their own individual entry. //scriptID list "short[]" is stored as an ID private HashMap<Short, short[]> sequences; //scriptID ->logicFontID/fontStyleID->componentFontNameID, //a 20-entry array (5-name x 4-style) for each script private HashMap<Short, Short[]> scriptFonts; //scriptID -> componentFontNameID private HashMap<Short, Short> scriptAllfonts; //scriptID -> exclusionRanges[] private HashMap<Short, int[]> exclusions; //scriptID -> fontpath private HashMap<Short, Short> awtfontpaths; //fontID -> fontID private HashMap<Short, Short> proportionals; //scriptID -> componentFontNameID private HashMap<Short, Short> scriptAllfontsMotif; //scriptID ->logicFontID/fontStyleID->componentFontNameID, private HashMap<Short, Short[]> scriptFontsMotif; //elcID -> stringID of alphabetic/XXXX private HashMap<Short, Short> alphabeticSuffix; private short[] fallbackScriptIDs; private String version; private String appendedfontpath; private void initLogicalNameStyle() { logicalFontIDs = new HashMap<String, Integer>(); fontStyleIDs = new HashMap<String, Integer>(); logicalFontIDs.put("serif", 0); logicalFontIDs.put("sansserif", 1); logicalFontIDs.put("monospaced", 2); logicalFontIDs.put("dialog", 3);Lines 1501–2000 of 2272. Previous lines Load more
System.out.println("\n----componentFontNameIDs--"); printTable(table_componentFontNameIDs, 1); System.out.println("\n----filenames-------------"); for (int ii = 0; ii < table_filenames.length; ii++) { if (table_filenames[ii] == -1) { System.out.println(" " + ii + " : null"); } else { System.out.println(" " + ii + " : " + getString(table_fontfileNameIDs[table_filenames[ii]])); } } System.out.println("\n----awtfontpaths---------"); for (int ii = 0; ii < table_awtfontpaths.length; ii++) { System.out.println(" " + getString(table_scriptIDs[ii]) + " : " + getString(table_awtfontpaths[ii])); } System.out.println("\n----proportionals--------"); for (int ii = 0; ii < table_proportionals.length; ii++) { System.out.println(" " + getString((short)table_componentFontNameIDs[table_proportionals[ii++]]) + " -> " + getString((short)table_componentFontNameIDs[table_proportionals[ii]])); } int i = 0; System.out.println("\n----alphabeticSuffix----"); while (i < table_alphabeticSuffix.length) { System.out.println(" " + getString(table_elcIDs[table_alphabeticSuffix[i++]]) + " -> " + getString(table_alphabeticSuffix[i++])); } System.out.println("\n----String Table---------"); System.out.println(" stringID: Num =" + table_stringIDs.length); System.out.println(" stringTable: Size=" + table_stringTable.length * 2); System.out.println("\n----fallbackScriptIDs---"); short[] fbsIDs = getShortArray(head[INDEX_fallbackScripts]); for (int ii = 0; ii < fbsIDs.length; ii++) { System.out.println(" " + getString(table_scriptIDs[fbsIDs[ii]])); } System.out.println("\n----appendedfontpath-----"); System.out.println(" " + getString(head[INDEX_appendedfontpath])); System.out.println("\n----Version--------------"); System.out.println(" " + getString(head[INDEX_version])); } ////////////////////////////////////////////////////////////////////// // Data table access methods // ////////////////////////////////////////////////////////////////////// /* Return the fontID of the platformFontName defined in this font config * by "LogicalFontName.StyleName.CharacterSubsetName" entry or * "allfonts.CharacterSubsetName" entry in properties format fc file. */ protected static short getComponentFontID(short scriptID, int fontIndex, int styleIndex) { short fid = table_scriptFonts[scriptID]; //System.out.println("fid=" + fid + "/ scriptID=" + scriptID + ", fi=" + fontIndex + ", si=" + styleIndex); if (fid >= 0) { //"allfonts" return fid; } else { return table_scriptFonts[-fid + fontIndex * NUM_STYLES + styleIndex]; } } /* Same as getCompoentFontID() except this method returns the fontID define by * "xxxx.motif" entry. */ protected static short getComponentFontIDMotif(short scriptID, int fontIndex, int styleIndex) { if (table_scriptFontsMotif.length == 0) { return 0; } short fid = table_scriptFontsMotif[scriptID]; if (fid >= 0) { //"allfonts" > 0 or "not defined" == 0 return fid; } else { return table_scriptFontsMotif[-fid + fontIndex * NUM_STYLES + styleIndex]; } } private static int[] getExclusionRanges(short scriptID) { short exID = table_exclusions[scriptID]; if (exID == 0) { return EMPTY_INT_ARRAY; } else { char[] exChar = getString(exID).toCharArray(); int[] exInt = new int[exChar.length / 2]; int i = 0; for (int j = 0; j < exInt.length; j++) { exInt[j] = (exChar[i++] << 16) + (exChar[i++] & 0xffff); } return exInt; } } private static boolean contains(short IDs[], short id, int limit) { for (int i = 0; i < limit; i++) { if (IDs[i] == id) { return true; } } return false; } /* Return the PlatformFontName from its fontID*/ protected static String getComponentFontName(short id) { if (id < 0) { return null; } return getString(table_componentFontNameIDs[id]); } private static String getComponentFileName(short id) { if (id < 0) { return null; } return getString(table_fontfileNameIDs[id]); } //componentFontID -> componentFileID private static short getComponentFileID(short nameID) { return table_filenames[nameID]; } private static String getScriptName(short scriptID) { return getString(table_scriptIDs[scriptID]); } private HashMap<String, Short> reorderScripts; protected short[] getCoreScripts(int fontIndex) { short elc = getInitELC(); /* System.out.println("getCoreScripts: elc=" + elc + ", fontIndex=" + fontIndex); short[] ss = getShortArray(table_sequences[elc * NUM_FONTS + fontIndex]); for (int i = 0; i < ss.length; i++) { System.out.println(" " + getString((short)table_scriptIDs[ss[i]])); } */ short[] scripts = getShortArray(table_sequences[elc * NUM_FONTS + fontIndex]); if (preferLocaleFonts) { if (reorderScripts == null) { reorderScripts = new HashMap<String, Short>(); } String[] ss = new String[scripts.length]; for (int i = 0; i < ss.length; i++) { ss[i] = getScriptName(scripts[i]); reorderScripts.put(ss[i], scripts[i]); } reorderSequenceForLocale(ss); for (int i = 0; i < ss.length; i++) { scripts[i] = reorderScripts.get(ss[i]); } } return scripts; } private static short[] getFallbackScripts() { return getShortArray(head[INDEX_fallbackScripts]); } private static void printTable(short[] list, int start) { for (int i = start; i < list.length; i++) { System.out.println(" " + i + " : " + getString(list[i])); } } private static short[] readShortTable(DataInputStream in, int len ) throws IOException { if (len == 0) { return EMPTY_SHORT_ARRAY; } short[] data = new short[len]; byte[] bb = new byte[len * 2]; in.read(bb); int i = 0,j = 0; while (i < len) { data[i++] = (short)(bb[j++] << 8 | (bb[j++] & 0xff)); } return data; } private static void writeShortTable(DataOutputStream out, short[] data) throws IOException { for (short val : data) { out.writeShort(val); } } private static short[] toList(HashMap<String, Short> map) { short[] list = new short[map.size()]; Arrays.fill(list, (short) -1); for (Entry<String, Short> entry : map.entrySet()) { list[entry.getValue()] = getStringID(entry.getKey()); } return list; } //runtime cache private static String[] stringCache; protected static String getString(short stringID) { if (stringID == 0) return null; /* if (loadingProperties) { return stringTable.substring(stringIDs[stringID], stringIDs[stringID+1]); } */ //sync if we want it to be MT-enabled if (stringCache[stringID] == null){ stringCache[stringID] = new String (table_stringTable, table_stringIDs[stringID], table_stringIDs[stringID+1] - table_stringIDs[stringID]); } return stringCache[stringID]; } private static short[] getShortArray(short shortArrayID) { String s = getString(shortArrayID); char[] cc = s.toCharArray(); short[] ss = new short[cc.length]; for (int i = 0; i < cc.length; i++) { ss[i] = (short)(cc[i] & 0xffff); } return ss; } private static short getStringID(String s) { if (s == null) { return (short)0; } short pos0 = (short)stringTable.length(); stringTable.append(s); short pos1 = (short)stringTable.length(); stringIDs[stringIDNum] = pos0; stringIDs[stringIDNum + 1] = pos1; stringIDNum++; if (stringIDNum + 1 >= stringIDs.length) { short[] tmp = new short[stringIDNum + 1000]; System.arraycopy(stringIDs, 0, tmp, 0, stringIDNum); stringIDs = tmp; } return (short)(stringIDNum - 1); } private static short getShortArrayID(short sa[]) { char[] cc = new char[sa.length]; for (int i = 0; i < sa.length; i ++) { cc[i] = (char)sa[i]; } String s = new String(cc); return getStringID(s); } //utility "empty" objects private static final int[] EMPTY_INT_ARRAY = new int[0]; private static final String[] EMPTY_STRING_ARRAY = new String[0]; private static final short[] EMPTY_SHORT_ARRAY = new short[0]; private static final String UNDEFINED_COMPONENT_FONT = "unknown"; ////////////////////////////////////////////////////////////////////////// //Convert the FontConfig data in Properties file to binary data tables // ////////////////////////////////////////////////////////////////////////// static class PropertiesHandler { public void load(InputStream in) throws IOException { initLogicalNameStyle(); initHashMaps(); FontProperties fp = new FontProperties(); fp.load(in); initBinaryTable(); } private void initBinaryTable() { //(0) head = new short[HEAD_LENGTH]; head[INDEX_scriptIDs] = (short)HEAD_LENGTH; table_scriptIDs = toList(scriptIDs); //(1)a: scriptAllfonts scriptID/allfonts -> componentFontNameID // b: scriptFonts scriptID -> componentFontNameID[20] //if we have a "allfonts.script" def, then we just put //the "-platformFontID" value in the slot, otherwise the slot //value is "offset" which "offset" is where 20 entries located //in the table attached. head[INDEX_scriptFonts] = (short)(head[INDEX_scriptIDs] + table_scriptIDs.length); int len = table_scriptIDs.length + scriptFonts.size() * 20; table_scriptFonts = new short[len]; for (Entry<Short, Short> entry : scriptAllfonts.entrySet()) { table_scriptFonts[entry.getKey().intValue()] = entry.getValue(); } int off = table_scriptIDs.length; for (Entry<Short, Short[]> entry : scriptFonts.entrySet()) { table_scriptFonts[entry.getKey().intValue()] = (short)-off; Short[] v = entry.getValue(); for (int i = 0; i < 20; i++) { if (v[i] != null) { table_scriptFonts[off++] = v[i]; } else { table_scriptFonts[off++] = 0; } } } //(2) head[INDEX_elcIDs] = (short)(head[INDEX_scriptFonts] + table_scriptFonts.length); table_elcIDs = toList(elcIDs); //(3) sequences elcID -> XXXX[1|5] -> scriptID[] head[INDEX_sequences] = (short)(head[INDEX_elcIDs] + table_elcIDs.length); table_sequences = new short[elcIDs.size() * NUM_FONTS]; for (Entry<Short, short[]> entry : sequences.entrySet()) { //table_sequences[entry.getKey().intValue()] = (short)-off; int k = entry.getKey().intValue(); short[] v = entry.getValue(); /* System.out.println("elc=" + k + "/" + getString((short)table_elcIDs[k])); short[] ss = getShortArray(v[0]); for (int i = 0; i < ss.length; i++) { System.out.println(" " + getString((short)table_scriptIDs[ss[i]])); } */ if (v.length == 1) { //the "allfonts" entries for (int i = 0; i < NUM_FONTS; i++) { table_sequences[k * NUM_FONTS + i] = v[0]; } } else { for (int i = 0; i < NUM_FONTS; i++) { table_sequences[k * NUM_FONTS + i] = v[i]; } } } //(4) head[INDEX_fontfileNameIDs] = (short)(head[INDEX_sequences] + table_sequences.length); table_fontfileNameIDs = toList(fontfileNameIDs); //(5) head[INDEX_componentFontNameIDs] = (short)(head[INDEX_fontfileNameIDs] + table_fontfileNameIDs.length); table_componentFontNameIDs = toList(componentFontNameIDs); //(6)componentFontNameID -> filenameID head[INDEX_filenames] = (short)(head[INDEX_componentFontNameIDs] + table_componentFontNameIDs.length); table_filenames = new short[table_componentFontNameIDs.length]; Arrays.fill(table_filenames, (short) -1); for (Entry<Short, Short> entry : filenames.entrySet()) { table_filenames[entry.getKey()] = entry.getValue(); } //(7)scriptID-> awtfontpath //the paths are stored as scriptID -> stringID in awtfontpahts head[INDEX_awtfontpaths] = (short)(head[INDEX_filenames] + table_filenames.length); table_awtfontpaths = new short[table_scriptIDs.length]; for (Entry<Short, Short> entry : awtfontpaths.entrySet()) { table_awtfontpaths[entry.getKey()] = entry.getValue(); } //(8)exclusions head[INDEX_exclusions] = (short)(head[INDEX_awtfontpaths] + table_awtfontpaths.length); table_exclusions = new short[scriptIDs.size()]; for (Entry<Short, int[]> entry : exclusions.entrySet()) { int[] exI = entry.getValue(); char[] exC = new char[exI.length * 2]; int j = 0; for (int i = 0; i < exI.length; i++) { exC[j++] = (char) (exI[i] >> 16); exC[j++] = (char) (exI[i] & 0xffff); } table_exclusions[entry.getKey()] = getStringID(new String (exC)); } //(9)proportionals head[INDEX_proportionals] = (short)(head[INDEX_exclusions] + table_exclusions.length); table_proportionals = new short[proportionals.size() * 2]; int j = 0; for (Entry<Short, Short> entry : proportionals.entrySet()) { table_proportionals[j++] = entry.getKey(); table_proportionals[j++] = entry.getValue(); } //(10) see (1) for info, the only difference is "xxx.motif" head[INDEX_scriptFontsMotif] = (short)(head[INDEX_proportionals] + table_proportionals.length); if (scriptAllfontsMotif.size() != 0 || scriptFontsMotif.size() != 0) { len = table_scriptIDs.length + scriptFontsMotif.size() * 20; table_scriptFontsMotif = new short[len]; for (Entry<Short, Short> entry : scriptAllfontsMotif.entrySet()) { table_scriptFontsMotif[entry.getKey().intValue()] = (short)entry.getValue(); } off = table_scriptIDs.length; for (Entry<Short, Short[]> entry : scriptFontsMotif.entrySet()) { table_scriptFontsMotif[entry.getKey().intValue()] = (short)-off; Short[] v = entry.getValue(); int i = 0; while (i < 20) { if (v[i] != null) { table_scriptFontsMotif[off++] = v[i]; } else { table_scriptFontsMotif[off++] = 0; } i++; } } } else { table_scriptFontsMotif = EMPTY_SHORT_ARRAY; } //(11)short[] alphabeticSuffix head[INDEX_alphabeticSuffix] = (short)(head[INDEX_scriptFontsMotif] + table_scriptFontsMotif.length); table_alphabeticSuffix = new short[alphabeticSuffix.size() * 2]; j = 0; for (Entry<Short, Short> entry : alphabeticSuffix.entrySet()) { table_alphabeticSuffix[j++] = entry.getKey(); table_alphabeticSuffix[j++] = entry.getValue(); } //(15)short[] fallbackScriptIDs; just put the ID in head head[INDEX_fallbackScripts] = getShortArrayID(fallbackScriptIDs); //(16)appendedfontpath head[INDEX_appendedfontpath] = getStringID(appendedfontpath); //(17)version head[INDEX_version] = getStringID(version); //(12)short[] StringIDs head[INDEX_stringIDs] = (short)(head[INDEX_alphabeticSuffix] + table_alphabeticSuffix.length); table_stringIDs = new short[stringIDNum + 1]; System.arraycopy(stringIDs, 0, table_stringIDs, 0, stringIDNum + 1); //(13)StringTable head[INDEX_stringTable] = (short)(head[INDEX_stringIDs] + stringIDNum + 1); table_stringTable = stringTable.toString().toCharArray(); //(14) head[INDEX_TABLEEND] = (short)(head[INDEX_stringTable] + stringTable.length()); //StringTable cache stringCache = new String[table_stringIDs.length]; } ////////////////////////////////////////////// private HashMap<String, Short> scriptIDs; //elc -> Encoding.Language.Country private HashMap<String, Short> elcIDs; //componentFontNameID starts from "1", "0" reserves for "undefined" private HashMap<String, Short> componentFontNameIDs; private HashMap<String, Short> fontfileNameIDs; private HashMap<String, Integer> logicalFontIDs; private HashMap<String, Integer> fontStyleIDs; //componentFontNameID -> fontfileNameID private HashMap<Short, Short> filenames; //elcID -> allfonts/logicalFont -> scriptID list //(1)if we have a "allfonts", then the length of the // value array is "1", otherwise it's 5, each font // must have their own individual entry. //scriptID list "short[]" is stored as an ID private HashMap<Short, short[]> sequences; //scriptID ->logicFontID/fontStyleID->componentFontNameID, //a 20-entry array (5-name x 4-style) for each script private HashMap<Short, Short[]> scriptFonts; //scriptID -> componentFontNameID private HashMap<Short, Short> scriptAllfonts; //scriptID -> exclusionRanges[] private HashMap<Short, int[]> exclusions; //scriptID -> fontpath private HashMap<Short, Short> awtfontpaths; //fontID -> fontID private HashMap<Short, Short> proportionals; //scriptID -> componentFontNameID private HashMap<Short, Short> scriptAllfontsMotif; //scriptID ->logicFontID/fontStyleID->componentFontNameID, private HashMap<Short, Short[]> scriptFontsMotif; //elcID -> stringID of alphabetic/XXXX private HashMap<Short, Short> alphabeticSuffix; private short[] fallbackScriptIDs; private String version; private String appendedfontpath; private void initLogicalNameStyle() { logicalFontIDs = new HashMap<String, Integer>(); fontStyleIDs = new HashMap<String, Integer>(); logicalFontIDs.put("serif", 0); logicalFontIDs.put("sansserif", 1); logicalFontIDs.put("monospaced", 2); logicalFontIDs.put("dialog", 3);