Changeset 8015 in josm for trunk/src/org/openstreetmap/josm/tools
- Timestamp:
- 2015-02-06T19:17:14+01:00 (10 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/tools
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/tools/PlatformHook.java
r7834 r8015 24 24 */ 25 25 public void preStartupHook(); 26 27 /** 28 * The afterPrefStartupHook will be called early, but after 29 * the preferences have been loaded and basic processing of 30 * command line arguments is finished. 31 * It is guaranteed to be called before the GUI setup has started. 32 */ 33 public void afterPrefStartupHook(); 26 34 27 35 /** -
trunk/src/org/openstreetmap/josm/tools/PlatformHookUnixoid.java
r7834 r8015 9 9 import java.awt.event.KeyEvent; 10 10 import java.io.BufferedReader; 11 import java.io.BufferedWriter; 11 12 import java.io.File; 13 import java.io.FileInputStream; 12 14 import java.io.IOException; 13 15 import java.io.InputStreamReader; 16 import java.io.OutputStream; 17 import java.io.OutputStreamWriter; 18 import java.io.Writer; 14 19 import java.net.URI; 15 20 import java.net.URISyntaxException; 16 21 import java.nio.charset.StandardCharsets; 22 import java.nio.file.FileSystems; 17 23 import java.nio.file.Files; 18 24 import java.nio.file.Path; … … 22 28 import java.security.NoSuchAlgorithmException; 23 29 import java.security.cert.CertificateException; 30 import java.util.ArrayList; 24 31 import java.util.Arrays; 32 import java.util.Collection; 33 import java.util.List; 34 import java.util.Properties; 25 35 26 36 import javax.swing.JOptionPane; … … 29 39 import org.openstreetmap.josm.gui.ExtendedDialog; 30 40 import org.openstreetmap.josm.gui.util.GuiHelper; 41 import org.openstreetmap.josm.data.Preferences.pref; 42 import org.openstreetmap.josm.data.Preferences.writeExplicitly; 31 43 32 44 /** … … 38 50 public class PlatformHookUnixoid implements PlatformHook { 39 51 52 /** 53 * Simple data class to hold information about a font. 54 * 55 * Used for fontconfig.properties files. 56 */ 57 public static class FontEntry { 58 /** 59 * The character subset. Basically a free identifier, but should 60 * be unique. 61 */ 62 @pref 63 public String charset; 64 /** 65 * Platform font name. 66 */ 67 @pref @writeExplicitly 68 public String name = ""; 69 /** 70 * File name. 71 */ 72 @pref @writeExplicitly 73 public String file = ""; 74 75 public FontEntry() { 76 } 77 78 public FontEntry(String charset, String name, String file) { 79 this.charset = charset; 80 this.name = name; 81 this.file = file; 82 } 83 } 84 40 85 private String osDescription; 41 86 42 87 @Override 43 88 public void preStartupHook() { 89 } 90 91 @Override 92 public void afterPrefStartupHook() { 44 93 } 45 94 … … 386 435 return Main.pref.getPreferencesDirectory(); 387 436 } 437 438 /** 439 * Add more fallback fonts to the Java runtime, in order to get 440 * support for more scripts. 441 * 442 * The font configuration in Java doesn't include some Indic scripts, 443 * even though MS Windows ships with fonts that cover these unicode 444 * ranges. 445 * 446 * To fix this, the fontconfig.properties template is copied to the JOSM 447 * cache folder. Then, the additional entries are added to the font 448 * configuration. Finally the system property "sun.awt.fontconfig" is set 449 * to the customized fontconfig.properties file. 450 * 451 * This is a crude hack, but better than no font display at all for these 452 * languages. 453 * There is no guarantee, that the template file 454 * ($JAVA_HOME/lib/fontconfig.properties.src) matches the default 455 * configuration (which is in a binary format). 456 * Furthermore, the system property "sun.awt.fontconfig" is undocumented and 457 * may no longer work in future versions of Java. 458 * 459 * @param templateFileName file name of the fontconfig.properties template file 460 */ 461 protected void extendFontconfig(String templateFileName) { 462 String customFontconfigFile = Main.pref.get("fontconfig.properties", null); 463 if (customFontconfigFile != null) { 464 Utils.updateSystemProperty("sun.awt.fontconfig", customFontconfigFile); 465 return; 466 } 467 if (!Main.pref.getBoolean("font.extended-unicode", true)) 468 return; 469 470 String javaLibPath = System.getProperty("java.home") + File.separator + "lib"; 471 Path templateFile = FileSystems.getDefault().getPath(javaLibPath, templateFileName); 472 if (!Files.isReadable(templateFile)) { 473 Main.warn("extended font config - unable to find font config template file "+templateFile.toString()); 474 return; 475 } 476 try { 477 Properties props = new Properties(); 478 props.load(new FileInputStream(templateFile.toFile())); 479 byte[] content = Files.readAllBytes(templateFile); 480 File cachePath = Main.pref.getCacheDirectory(); 481 Path fontconfigFile = cachePath.toPath().resolve("fontconfig.properties"); 482 OutputStream os = Files.newOutputStream(fontconfigFile); 483 os.write(content); 484 try (Writer w = new BufferedWriter(new OutputStreamWriter(os))) { 485 Collection<FontEntry> extrasPref = Main.pref.getListOfStructs( 486 "font.extended-unicode.extra-items", getAdditionalFonts(), FontEntry.class); 487 Collection<FontEntry> extras = new ArrayList<>(); 488 w.append("\n\n# Added by JOSM to extend unicode coverage of Java font support:\n\n"); 489 List<String> allCharSubsets = new ArrayList<>(); 490 for (FontEntry entry: extrasPref) { 491 Collection<String> fontsAvail = getInstalledFonts(); 492 if (fontsAvail != null && fontsAvail.contains(entry.file.toUpperCase())) { 493 if (!allCharSubsets.contains(entry.charset)) { 494 allCharSubsets.add(entry.charset); 495 extras.add(entry); 496 } else { 497 Main.trace("extended font config - already registered font for charset ''{0}'' - skipping ''{1}''", 498 entry.charset, entry.name); 499 } 500 } else { 501 Main.trace("extended font config - Font ''{0}'' not found on system - skipping", entry.name); 502 } 503 } 504 for (FontEntry entry: extras) { 505 allCharSubsets.add(entry.charset); 506 if ("".equals(entry.name)) { 507 continue; 508 } 509 String key = "allfonts." + entry.charset; 510 String value = entry.name; 511 String prevValue = props.getProperty(key); 512 if (prevValue != null && !prevValue.equals(value)) { 513 Main.warn("extended font config - overriding ''{0}={1}'' with ''{2}''", key, prevValue, value); 514 } 515 w.append(key + "=" + value + "\n"); 516 } 517 w.append("\n"); 518 for (FontEntry entry: extras) { 519 if ("".equals(entry.name) || "".equals(entry.file)) { 520 continue; 521 } 522 String key = "filename." + entry.name.replace(" ", "_"); 523 String value = entry.file; 524 String prevValue = props.getProperty(key); 525 if (prevValue != null && !prevValue.equals(value)) { 526 Main.warn("extended font config - overriding ''{0}={1}'' with ''{2}''", key, prevValue, value); 527 } 528 w.append(key + "=" + value + "\n"); 529 } 530 w.append("\n"); 531 String fallback = props.getProperty("sequence.fallback"); 532 if (fallback != null) { 533 w.append("sequence.fallback=" + fallback + "," + Utils.join(",", allCharSubsets) + "\n"); 534 } else { 535 w.append("sequence.fallback=" + Utils.join(",", allCharSubsets) + "\n"); 536 } 537 } 538 Utils.updateSystemProperty("sun.awt.fontconfig", fontconfigFile.toString()); 539 } catch (IOException ex) { 540 Main.error(ex); 541 } 542 } 543 544 /** 545 * Get a list of fonts that are installed on the system. 546 * 547 * Must be done without triggering the Java Font initialization. 548 * (See {@link #extendFontconfig(java.lang.String)}, have to set system 549 * property first, which is then read by sun.awt.FontConfiguration upon 550 * initialization.) 551 * 552 * @return list of file names 553 */ 554 public Collection<String> getInstalledFonts() { 555 throw new UnsupportedOperationException(); 556 } 557 558 /** 559 * Get default list of additional fonts to add to the configuration. 560 * 561 * Java will choose thee first font in the list that can render a certain 562 * character. 563 * 564 * @return list of FontEntry objects 565 */ 566 public Collection<FontEntry> getAdditionalFonts() { 567 throw new UnsupportedOperationException(); 568 } 388 569 } -
trunk/src/org/openstreetmap/josm/tools/PlatformHookWindows.java
r8014 r8015 29 29 30 30 import java.awt.GraphicsEnvironment; 31 import java.io.BufferedWriter;32 31 import java.io.File; 33 import java.io.FileInputStream;34 32 import java.io.IOException; 35 import java.io.OutputStream; 36 import java.io.OutputStreamWriter; 37 import java.io.Writer; 33 import java.nio.file.DirectoryStream; 38 34 import java.nio.file.FileSystems; 39 35 import java.nio.file.Files; … … 51 47 import java.security.spec.X509EncodedKeySpec; 52 48 import java.util.ArrayList; 53 import java.util.Arrays;54 49 import java.util.Collection; 55 50 import java.util.Enumeration; 56 51 import java.util.List; 57 import java.util.Properties;58 52 59 53 import javax.swing.JOptionPane; 54 60 55 import org.openstreetmap.josm.Main; 61 56 … … 96 91 97 92 @Override 98 public void preStartupHook() { 99 extendFontconfig(); 100 } 101 102 /** 103 * Add more fallback fonts to the Java runtime, in order to get wider 104 * unicode support. 105 * 106 * The font configuration in Java doesn't include some Indic scripts, 107 * even though MS Windows ships with fonts that cover these unicode 108 * ranges. 109 * 110 * To fix this, the fontconfig.properties template is copied to the JOSM 111 * cache folder. Then, the additional entries are added to the font 112 * configuration. Finally the system property "sun.awt.fontconfig" is set 113 * to the customized fontconfig.properties file. 114 * 115 * This is a crude hack, but better than no font display at all for these 116 * languages. 117 * There is no guarantee, that the template file 118 * ($JAVA_HOME/lib/fontconfig.properties.src) matches the default 119 * configuration (which is in a binary format). 120 * Furthermore, the system property "sun.awt.fontconfig" is undocumented and 121 * may no longer work in future versions of Java. 122 */ 123 protected void extendFontconfig() { 124 String customFontconfigFile = Main.pref.get("fontconfig.properties", null); 125 if (customFontconfigFile != null) { 126 Utils.updateSystemProperty("sun.awt.fontconfig", customFontconfigFile); 127 return; 128 } 129 if (!Main.pref.getBoolean("font.extended-unicode", true)) 130 return; 131 String javaLibPath = System.getProperty("java.home") + File.separator + "lib"; 132 Path templateFile = FileSystems.getDefault().getPath(javaLibPath, "fontconfig.properties.src"); 133 if (!Files.isReadable(templateFile)) { 134 Main.warn("extended unicode - unable to find font config template file "+templateFile.toString()); 135 return; 136 } 137 try { 138 Properties props = new Properties(); 139 props.load(new FileInputStream(templateFile.toFile())); 140 byte[] content = Files.readAllBytes(templateFile); 141 File cachePath = Main.pref.getCacheDirectory(); 142 Path fontconfigFile = cachePath.toPath().resolve("fontconfig.properties"); 143 OutputStream os = Files.newOutputStream(fontconfigFile); 144 os.write(content); 145 try (Writer w = new BufferedWriter(new OutputStreamWriter(os))) { 146 Collection<Collection<String>> def = new ArrayList<>(); 147 def.add(Arrays.asList("devanagari", "", "")); // just include in fallback list 148 // no font definition needed 149 // all of the following fonts are available in Win XP and later 150 def.add(Arrays.asList("gujarati", "Shruti", "SHRUTI.TTF")); 151 def.add(Arrays.asList("kannada", "Tunga", "TUNGA.TTF")); 152 def.add(Arrays.asList("gurmuhi", "Raavi", "RAAVI.TTF")); 153 def.add(Arrays.asList("tamil", "Latha", "LATHA.TTF")); 154 def.add(Arrays.asList("telugu", "Gautami", "GAUTAMI.TTF")); 155 def.add(Arrays.asList("bengali", "Vrinda", "VRINDA.TTF")); 156 def.add(Arrays.asList("syriac", "Estrangelo Edessa", "ESTRE.TTF")); // ISO 639: arc 157 def.add(Arrays.asList("thaana", "MV Boli", "MVBOLI.TTF")); // ISO 639: dv 158 def.add(Arrays.asList("malayalam", "Kartika", "KARTIKA.TTF")); // ISO 639: ml; since XP SP2 159 Collection<Collection<String>> additions = 160 Main.pref.getArray("font.extended-unicode.added-items", def); 161 w.append("\n\n# Added by JOSM to extend unicode coverage of Java font support:\n\n"); 162 List<String> allCharSubsets = new ArrayList<>(); 163 for (Collection<String> entry: additions) { 164 List<String> lentry = new ArrayList<>(entry); 165 String charSubset = lentry.get(0); 166 allCharSubsets.add(charSubset); 167 String platformFontName = lentry.get(1); 168 if ("".equals(platformFontName)) { 169 continue; 170 } 171 String key = "allfonts." + charSubset; 172 String value = platformFontName; 173 String prevValue = props.getProperty(key); 174 if (prevValue != null && !prevValue.equals(value)) { 175 Main.warn("extended unicode - overriding " + key + "=" + prevValue + " with " + value); 176 } 177 w.append(key + "=" + value + "\n"); 178 } 179 w.append("\n"); 180 for (Collection<String> entry: additions) { 181 List<String> lentry = new ArrayList<>(entry); 182 String platformFontName = lentry.get(1); 183 String fontFile = lentry.get(2); 184 if ("".equals(platformFontName) || "".equals(fontFile)) { 185 continue; 186 } 187 String key = "filename." + platformFontName; 188 String value = fontFile; 189 String prevValue = props.getProperty(key); 190 if (prevValue != null && !prevValue.equals(value)) { 191 Main.warn("extended unicode - overriding " + key + "=" + prevValue + " with " + value); 192 } 193 w.append(key + "=" + value + "\n"); 194 } 195 w.append("\n"); 196 String fallback = props.getProperty("sequence.fallback"); 197 if (fallback != null) { 198 w.append("sequence.fallback=" + fallback + "," + Utils.join(",", allCharSubsets) + "\n"); 199 } else { 200 w.append("sequence.fallback=" + Utils.join(",", allCharSubsets) + "\n"); 201 } 202 } 203 Utils.updateSystemProperty("sun.awt.fontconfig", fontconfigFile.toString()); 204 } catch (IOException ex) { 205 Main.error(ex); 206 } 207 } 208 93 public void afterPrefStartupHook() { 94 extendFontconfig("fontconfig.properties.src"); 95 } 96 209 97 @Override 210 98 public void openUrl(String url) throws IOException { … … 420 308 return new File(System.getenv("APPDATA"), "JOSM"); 421 309 } 310 311 @Override 312 public Collection<String> getInstalledFonts() { 313 // Cannot use GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() 314 // because we have to set the system property before Java initializes its fonts. 315 // Use more low-level method to find the installed fonts. 316 List<String> fontsAvail = new ArrayList<>(); 317 Path fontPath = FileSystems.getDefault().getPath(System.getenv("SYSTEMROOT"), "Fonts"); 318 try (DirectoryStream<Path> ds = Files.newDirectoryStream(fontPath)) { 319 for (Path p : ds) { 320 fontsAvail.add(p.getFileName().toString().toUpperCase()); 321 } 322 } catch (IOException ex) { 323 Main.warn("extended font config - failed to load available Fonts"); 324 fontsAvail = null; 325 } 326 fontsAvail.add(""); // for devanagari 327 return fontsAvail; 328 } 329 330 @Override 331 public Collection<FontEntry> getAdditionalFonts() { 332 Collection<FontEntry> def = new ArrayList<>(); 333 def.add(new FontEntry("devanagari", "", "")); // just include in fallback list 334 // font already defined in template 335 // Win 8 (and later) 336 def.add(new FontEntry("myanmar", "Myanmar Text", "MMRTEXT.TTF")); // ISO 639: my 337 338 // Win 7 and later 339 def.add(new FontEntry("nko_tifinagh_vai_osmanya", "Ebrima", "EBRIMA.TTF")); // ISO 639: ber 340 def.add(new FontEntry("khmer1", "Khmer UI", "KHMERUI.TTF")); // ISO 639: km 341 def.add(new FontEntry("lao1", "Lao UI", "LAOUI.TTF")); // ISO 639: lo 342 343 // Win Vista and later: 344 def.add(new FontEntry("ethiopic", "Nyala", "NYALA.TTF")); // ISO 639: am,gez,ti 345 def.add(new FontEntry("tibetan", "Microsoft Himalaya", "HIMALAYA.TTF")); // ISO 639: bo,dz 346 def.add(new FontEntry("cherokee", "Plantagenet Cherokee", "PLANTC.TTF")); // ISO 639: chr 347 def.add(new FontEntry("unified_canadian", "Euphemia", "EUPHEMIA.TTF")); // ISO 639: cr,in 348 def.add(new FontEntry("khmer2", "DaunPenh", "DAUNPENH.TTF")); // ISO 639: km 349 def.add(new FontEntry("khmer3", "MoolBoran", "MOOLBOR.TTF")); // ISO 639: km 350 def.add(new FontEntry("lao_thai", "DokChampa", "DOKCHAMP.TTF")); // ISO 639: lo 351 def.add(new FontEntry("mongolian", "Mongolian Baiti", "MONBAITI.TTF")); // ISO 639: mn 352 def.add(new FontEntry("oriya", "Kalinga", "KALINGA.TTF")); // ISO 639: or 353 def.add(new FontEntry("sinhala", "Iskoola Pota", "ISKPOTA.TTF")); // ISO 639: si 354 355 // Win XP and later 356 def.add(new FontEntry("gujarati", "Shruti", "SHRUTI.TTF")); 357 def.add(new FontEntry("kannada", "Tunga", "TUNGA.TTF")); 358 def.add(new FontEntry("gurmuhi", "Raavi", "RAAVI.TTF")); 359 def.add(new FontEntry("tamil", "Latha", "LATHA.TTF")); 360 def.add(new FontEntry("telugu", "Gautami", "GAUTAMI.TTF")); 361 def.add(new FontEntry("bengali", "Vrinda", "VRINDA.TTF")); 362 def.add(new FontEntry("syriac", "Estrangelo Edessa", "ESTRE.TTF")); // ISO 639: arc 363 def.add(new FontEntry("thaana", "MV Boli", "MVBOLI.TTF")); // ISO 639: dv 364 def.add(new FontEntry("malayalam", "Kartika", "KARTIKA.TTF")); // ISO 639: ml; since XP SP2 365 366 // Comes with MS Office & Outlook 2000. Good unicode coverage, so add if available. 367 def.add(new FontEntry("arialuni", "Arial Unicode MS", "ARIALUNI.TTF")); 368 369 return def; 370 } 371 422 372 }
Note:
See TracChangeset
for help on using the changeset viewer.