350 table_componentFontNameIDs = readShortTable(in, tableSizes[INDEX_componentFontNameIDs]); 351 table_filenames = readShortTable(in, tableSizes[INDEX_filenames]); 352 table_awtfontpaths = readShortTable(in, tableSizes[INDEX_awtfontpaths]); 353 table_exclusions = readShortTable(in, tableSizes[INDEX_exclusions]); 354 table_proportionals = readShortTable(in, tableSizes[INDEX_proportionals]); 355 table_scriptFontsMotif = readShortTable(in, tableSizes[INDEX_scriptFontsMotif]); 356 table_alphabeticSuffix = readShortTable(in, tableSizes[INDEX_alphabeticSuffix]); 357 table_stringIDs = readShortTable(in, tableSizes[INDEX_stringIDs]); 358 359 //StringTable cache 360 stringCache = new String[table_stringIDs.length + 1]; 361 362 int len = tableSizes[INDEX_stringTable]; 363 byte[] bb = new byte[len * 2]; 364 table_stringTable = new char[len]; 365 in.read(bb); 366 int i = 0, j = 0; 367 while (i < len) { 368 table_stringTable[i++] = (char)(bb[j++] << 8 | (bb[j++] & 0xff)); 369 } 370 if (verbose) { 371 dump(); 372 } 373 } 374 375 /* Generate a binary format font configuration from internal data 376 * tables. 377 */ 378 public static void saveBinary(OutputStream out) throws IOException { 379 sanityCheck(); 380 381 DataOutputStream dataOut = new DataOutputStream(out); 382 writeShortTable(dataOut, head); 383 writeShortTable(dataOut, table_scriptIDs); 384 writeShortTable(dataOut, table_scriptFonts); 385 writeShortTable(dataOut, table_elcIDs); 386 writeShortTable(dataOut, table_sequences); 387 writeShortTable(dataOut, table_fontfileNameIDs); 388 writeShortTable(dataOut, table_componentFontNameIDs); 389 writeShortTable(dataOut, table_filenames); 2103 map.put(key, (short)map.size()); 2104 return map.get(key); 2105 } 2106 return ret; 2107 } 2108 2109 @SuppressWarnings("serial") // JDK-implementation class 2110 class FontProperties extends Properties { 2111 public synchronized Object put(Object k, Object v) { 2112 parseProperty((String)k, (String)v); 2113 return null; 2114 } 2115 } 2116 2117 private void parseProperty(String key, String value) { 2118 if (key.startsWith("filename.")) { 2119 //the only special case is "MingLiu_HKSCS" which has "_" in its 2120 //facename, we don't want to replace the "_" with " " 2121 key = key.substring(9); 2122 if (!"MingLiU_HKSCS".equals(key)) { 2123 key = key.replace('_', ' '); 2124 } 2125 Short faceID = getID(componentFontNameIDs, key); 2126 Short fileID = getID(fontfileNameIDs, value); 2127 //System.out.println("faceID=" + faceID + "/" + key + " -> " 2128 // + "fileID=" + fileID + "/" + value); 2129 filenames.put(faceID, fileID); 2130 } else if (key.startsWith("exclusion.")) { 2131 key = key.substring(10); 2132 exclusions.put(getID(scriptIDs,key), parseExclusions(key,value)); 2133 } else if (key.startsWith("sequence.")) { 2134 key = key.substring(9); 2135 boolean hasDefault = false; 2136 boolean has1252 = false; 2137 2138 //get the scriptID list 2139 String[] ss = splitSequence(value).toArray(EMPTY_STRING_ARRAY); 2140 short [] sa = new short[ss.length]; 2141 for (int i = 0; i < ss.length; i++) { 2142 if ("alphabetic/default".equals(ss[i])) { 2143 //System.out.println(key + " -> " + ss[i]); | 350 table_componentFontNameIDs = readShortTable(in, tableSizes[INDEX_componentFontNameIDs]); 351 table_filenames = readShortTable(in, tableSizes[INDEX_filenames]); 352 table_awtfontpaths = readShortTable(in, tableSizes[INDEX_awtfontpaths]); 353 table_exclusions = readShortTable(in, tableSizes[INDEX_exclusions]); 354 table_proportionals = readShortTable(in, tableSizes[INDEX_proportionals]); 355 table_scriptFontsMotif = readShortTable(in, tableSizes[INDEX_scriptFontsMotif]); 356 table_alphabeticSuffix = readShortTable(in, tableSizes[INDEX_alphabeticSuffix]); 357 table_stringIDs = readShortTable(in, tableSizes[INDEX_stringIDs]); 358 359 //StringTable cache 360 stringCache = new String[table_stringIDs.length + 1]; 361 362 int len = tableSizes[INDEX_stringTable]; 363 byte[] bb = new byte[len * 2]; 364 table_stringTable = new char[len]; 365 in.read(bb); 366 int i = 0, j = 0; 367 while (i < len) { 368 table_stringTable[i++] = (char)(bb[j++] << 8 | (bb[j++] & 0xff)); 369 } 370 if (System.getProperty("os.name").contains("AIX")) { 371 // Fix broken fontconfig.bfc on AIX 372 // Encoding name "ucs2.cjk_*" needs to handle as "ucs2.cjk *" 373 HashMap<String, Short> fixComponentFontNameID = new HashMap<String, Short>(); 374 for (short ii = 0; ii < table_componentFontNameIDs.length; ii++) { 375 String fontName = getString(table_componentFontNameIDs[ii]); 376 if (fontName.indexOf("-ucs2.cjk ") > -1) { 377 fixComponentFontNameID.put(fontName, ii); 378 } 379 } 380 for (short ii = 0; ii < table_componentFontNameIDs.length; ii++) { 381 String fontName = getString(table_componentFontNameIDs[ii]); 382 if (fontName.indexOf("-ucs2.cjk_") > -1) { 383 fontName = fontName.replace('_', ' '); 384 if (fixComponentFontNameID.containsKey(fontName)) { 385 short jj = fixComponentFontNameID.get(fontName); 386 table_filenames[ii] = table_filenames[jj]; 387 } 388 } 389 } 390 } 391 if (verbose) { 392 dump(); 393 } 394 } 395 396 /* Generate a binary format font configuration from internal data 397 * tables. 398 */ 399 public static void saveBinary(OutputStream out) throws IOException { 400 sanityCheck(); 401 402 DataOutputStream dataOut = new DataOutputStream(out); 403 writeShortTable(dataOut, head); 404 writeShortTable(dataOut, table_scriptIDs); 405 writeShortTable(dataOut, table_scriptFonts); 406 writeShortTable(dataOut, table_elcIDs); 407 writeShortTable(dataOut, table_sequences); 408 writeShortTable(dataOut, table_fontfileNameIDs); 409 writeShortTable(dataOut, table_componentFontNameIDs); 410 writeShortTable(dataOut, table_filenames); 2124 map.put(key, (short)map.size()); 2125 return map.get(key); 2126 } 2127 return ret; 2128 } 2129 2130 @SuppressWarnings("serial") // JDK-implementation class 2131 class FontProperties extends Properties { 2132 public synchronized Object put(Object k, Object v) { 2133 parseProperty((String)k, (String)v); 2134 return null; 2135 } 2136 } 2137 2138 private void parseProperty(String key, String value) { 2139 if (key.startsWith("filename.")) { 2140 //the only special case is "MingLiu_HKSCS" which has "_" in its 2141 //facename, we don't want to replace the "_" with " " 2142 key = key.substring(9); 2143 if (!"MingLiU_HKSCS".equals(key)) { 2144 String[] parts = key.split("-"); 2145 if (parts.length == 15) { 2146 // Underscore->Space conversion only applies 2147 // against FOUNDRY(1), FAMILY_NAME(2), WEIGHT_NAME(3) 2148 // SLANT(4), SETWIDTH_NAME(5), ADD_STYLE_NAME(6) on XLFD 2149 for (int i = 1; i < 7; i++) { 2150 parts[i] = parts[i].replace('_', ' '); 2151 } 2152 key = String.join("-", parts); 2153 } else { 2154 key = key.replace('_', ' '); 2155 } 2156 } 2157 Short faceID = getID(componentFontNameIDs, key); 2158 Short fileID = getID(fontfileNameIDs, value); 2159 //System.out.println("faceID=" + faceID + "/" + key + " -> " 2160 // + "fileID=" + fileID + "/" + value); 2161 filenames.put(faceID, fileID); 2162 } else if (key.startsWith("exclusion.")) { 2163 key = key.substring(10); 2164 exclusions.put(getID(scriptIDs,key), parseExclusions(key,value)); 2165 } else if (key.startsWith("sequence.")) { 2166 key = key.substring(9); 2167 boolean hasDefault = false; 2168 boolean has1252 = false; 2169 2170 //get the scriptID list 2171 String[] ss = splitSequence(value).toArray(EMPTY_STRING_ARRAY); 2172 short [] sa = new short[ss.length]; 2173 for (int i = 0; i < ss.length; i++) { 2174 if ("alphabetic/default".equals(ss[i])) { 2175 //System.out.println(key + " -> " + ss[i]); |