1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /** 18 * @author Ilya S. Okomin 19 * @version $Revision$ 20 */ 21 package org.apache.harmony.awt.gl.font; 22 23 import java.awt.Font; 24 import java.awt.peer.FontPeer; 25 import java.io.File; 26 import java.io.FileInputStream; 27 import java.io.IOException; 28 import java.lang.ref.ReferenceQueue; 29 import java.lang.ref.SoftReference; 30 import java.util.Enumeration; 31 import java.util.Hashtable; 32 import java.util.Locale; 33 import java.util.Properties; 34 import java.util.Vector; 35 36 import org.apache.harmony.awt.gl.CommonGraphics2DFactory; 37 import org.apache.harmony.luni.util.NotImplementedException; 38 39 40 public abstract class FontManager { 41 42 //???AWT 43 boolean NOT_IMP = false; 44 45 /** 46 * array of font families names 47 */ 48 public String[] allFamilies; 49 50 public static final String DEFAULT_NAME = "Default"; /* Default font name */ //$NON-NLS-1$ 51 public static final String DIALOG_NAME = "Dialog"; /* Dialog font name */ //$NON-NLS-1$ 52 53 /** 54 * Set of constants applicable to the TrueType 'name' table. 55 */ 56 public static final byte FAMILY_NAME_ID = 1; /* Family name identifier */ 57 public static final byte FONT_NAME_ID = 4; /* Full font name identifier */ 58 public static final byte POSTSCRIPT_NAME_ID = 6; /* PostScript name identifier */ 59 public static final short ENGLISH_LANGID = 0x0409; /* English (United States)language identifier */ 60 61 /** 62 * Set of constants describing font type. 63 */ 64 public static final byte FONT_TYPE_TT = 4; /* TrueType type (TRUETYPE_FONTTYPE) */ 65 public static final byte FONT_TYPE_T1 = 2; /* Type1 type (DEVICE_FONTTYPE) */ 66 public static final byte FONT_TYPE_UNDEF = 0; /* Undefined type */ 67 68 // logical family types (indices in FontManager.LOGICAL_FONT_NAMES) 69 static final int DIALOG = 3; // FF_SWISS 70 static final int SANSSERIF = 1; // FF_SWISS 71 static final int DIALOGINPUT = 4; // FF_MODERN 72 static final int MONOSPACED = 2; // FF_MODERN 73 static final int SERIF = 0; // FF_ROMAN 74 75 76 /** 77 * FontProperty related constants. 78 */ 79 public static final String PLATFORM_FONT_NAME = "PlatformFontName"; //$NON-NLS-1$ 80 public static final String LOGICAL_FONT_NAME = "LogicalFontName"; //$NON-NLS-1$ 81 public static final String COMPONENT_INDEX = "ComponentIndex"; //$NON-NLS-1$ 82 public static final String STYLE_INDEX = "StyleIndex"; //$NON-NLS-1$ 83 84 public static final String[] FONT_MAPPING_KEYS = { 85 "LogicalFontName.StyleName.ComponentIndex", "LogicalFontName.ComponentIndex" //$NON-NLS-1$ //$NON-NLS-2$ 86 }; 87 88 public static final String FONT_CHARACTER_ENCODING = "fontcharset.LogicalFontName.ComponentIndex"; //$NON-NLS-1$ 89 90 public static final String EXCLUSION_RANGES = "exclusion.LogicalFontName.ComponentIndex"; //$NON-NLS-1$ 91 92 public static final String FONT_FILE_NAME = "filename.PlatformFontName"; //$NON-NLS-1$ 93 94 /** 95 * Available logical font families names. 96 */ 97 public static final String[] LOGICAL_FONT_FAMILIES = { 98 "Serif", "SansSerif", "Monospaced", "Dialog", "DialogInput" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 99 }; 100 101 /** 102 * Available logical font names. 103 */ 104 public static final String[] LOGICAL_FONT_NAMES = { 105 "serif", "serif.plain", "serif.bold", "serif.italic", "serif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 106 "sansserif", "sansserif.plain", "sansserif.bold", "sansserif.italic", "sansserif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 107 "monospaced", "monospaced.plain", "monospaced.bold", "monospaced.italic", "monospaced.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 108 "dialog", "dialog.plain", "dialog.bold", "dialog.italic", "dialog.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 109 "dialoginput", "dialoginput.plain", "dialoginput.bold", "dialoginput.italic", "dialoginput.bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 110 }; 111 112 /** 113 * Available logical font face names. 114 */ 115 public static final String[] LOGICAL_FONT_FACES = { 116 "Serif", "Serif.plain", "Serif.bold", "Serif.italic", "Serif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 117 "Sansserif", "Sansserif.plain", "Sansserif.bold", "Sansserif.italic", "Sansserif.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 118 "Monospaced", "Monospaced.plain", "Monospaced.bold", "Monospaced.italic", "Monospaced.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 119 "Dialog", "Dialog.plain", "Dialog.bold", "Dialog.italic", "Dialog.bolditalic", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 120 "Dialoginput", "Dialoginput.plain", "Dialoginput.bold", "Dialoginput.italic", "Dialoginput.bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 121 }; 122 123 /** 124 * Set of font style names. 125 * Font.getStyle() corresponds to indexes in STYLE_NAMES array. 126 */ 127 public static final String[] STYLE_NAMES = { 128 "plain", "bold", "italic", "bolditalic" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ 129 }; 130 131 /** 132 * Logical font styles names table where font styles names used 133 * as the key and the value is the index of this style name. 134 */ 135 private static final Hashtable<String, Integer> style_keys = new Hashtable<String, Integer>(4); 136 137 /** 138 * Initialize font styles keys table. 139 */ 140 static { 141 for (int i = 0; i < STYLE_NAMES.length; i++){ 142 style_keys.put(STYLE_NAMES[i], Integer.valueOf(i)); 143 } 144 } 145 146 /** 147 * Return font style from the logical style name. 148 * 149 * @param lName style name of the logical face 150 */ 151 public static int getLogicalStyle(String lName){ 152 Integer value = style_keys.get(lName); 153 return value != null ? value.intValue(): -1; 154 } 155 156 /** 157 * Set of possible "os" property values. 158 */ 159 public static final String[] OS_VALUES = { 160 "NT", "98", "2000", "Me", "XP", // For Windows //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 161 "Redhat", "Turbo", "SuSE" // For Linux //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 162 }; 163 164 /** 165 * Set of possible font.property file names. 166 * Language, Country, Encoding, OS, Version should be replaced with 167 * the values from current configuration. 168 */ 169 public static final String[] FP_FILE_NAMES = { 170 "/lib/font.properties.Language_Country_Encoding.OSVersion", //$NON-NLS-1$ 171 "/lib/font.properties.Language_Country_Encoding.OS", //$NON-NLS-1$ 172 "/lib/font.properties.Language_Country_Encoding.Version", //$NON-NLS-1$ 173 "/lib/font.properties.Language_Country_Encoding", //$NON-NLS-1$ 174 "/lib/font.properties.Language_Country.OSVersion", //$NON-NLS-1$ 175 "/lib/font.properties.Language_Country.OS", //$NON-NLS-1$ 176 "/lib/font.properties.Language_Country.Version", //$NON-NLS-1$ 177 "/lib/font.properties.Language_Country", //$NON-NLS-1$ 178 "/lib/font.properties.Language_Encoding.OSVersion", //$NON-NLS-1$ 179 "/lib/font.properties.Language_Encoding.OS", //$NON-NLS-1$ 180 "/lib/font.properties.Language_Encoding.Version", //$NON-NLS-1$ 181 "/lib/font.properties.Language_Encoding", //$NON-NLS-1$ 182 "/lib/font.properties.Language.OSVersion", //$NON-NLS-1$ 183 "/lib/font.properties.Language.OS", //$NON-NLS-1$ 184 "/lib/font.properties.Language.Version", //$NON-NLS-1$ 185 "/lib/font.properties.Language", //$NON-NLS-1$ 186 "/lib/font.properties.Encoding.OSVersion", //$NON-NLS-1$ 187 "/lib/font.properties.Encoding.OS", //$NON-NLS-1$ 188 "/lib/font.properties.Encoding.Version", //$NON-NLS-1$ 189 "/lib/font.properties.Encoding", //$NON-NLS-1$ 190 "/lib/font.properties.OSVersion", //$NON-NLS-1$ 191 "/lib/font.properties.OS", //$NON-NLS-1$ 192 "/lib/font.properties.Version", //$NON-NLS-1$ 193 "/lib/font.properties" //$NON-NLS-1$ 194 }; 195 196 /** 197 * Table with all available font properties corresponding 198 * to the current system configuration. 199 */ 200 public Hashtable<String, Vector<FontProperty>> fProperties = new Hashtable<String, Vector<FontProperty>>(); 201 202 public FontManager(){ 203 allFamilies = getAllFamilies(); 204 /* 205 * Creating and registering shutdown hook to free resources 206 * before object is destroyed. 207 */ 208 //???AWT 209 //DisposeNativeHook shutdownHook = new DisposeNativeHook(); 210 //Runtime.getRuntime().addShutdownHook(shutdownHook); 211 } 212 213 /** 214 * Maximum number of unreferenced font peers to keep. 215 */ 216 public static final int EMPTY_FONTS_CAPACITY = 10; 217 218 /** 219 * Locale - Language ID hash table. 220 */ 221 Hashtable<String, Short> tableLCID = new Hashtable<String, Short>(); 222 223 /** 224 * Hash table that contains FontPeers instances. 225 */ 226 public Hashtable<String, HashMapReference> fontsTable = new Hashtable<String, HashMapReference>(); 227 228 /** 229 * ReferenceQueue for HashMapReference objects to check 230 * if they were collected by garbage collector. 231 */ 232 public ReferenceQueue<FontPeer> queue = new ReferenceQueue<FontPeer>(); 233 234 /** 235 * Singleton instance 236 */ 237 public final static FontManager inst = CommonGraphics2DFactory.inst.getFontManager(); 238 239 /** 240 * Gets singleton instance of FontManager 241 * 242 * @return instance of FontManager implementation 243 */ 244 public static FontManager getInstance() { 245 return inst; 246 } 247 248 /** 249 * Returns platform-dependent Font peer created from the specified 250 * Font object from the table with cached FontPeers instances. 251 * 252 * Note, this method checks whether FontPeer with specified parameters 253 * exists in the table with cached FontPeers' instances. If there is no needed 254 * instance - it is created and cached. 255 * 256 * @param fontName name of the font 257 * @param _fontStyle style of the font 258 * @param size font size 259 * 260 * @return platform dependent FontPeer implementation created from 261 * the specified parameters 262 */ 263 public FontPeer getFontPeer(String fontName, int _fontStyle, int size) { 264 updateFontsTable(); 265 266 FontPeer peer = null; 267 String key; 268 String name; 269 int fontStyle = _fontStyle; 270 271 int logicalIndex = getLogicalFaceIndex(fontName); 272 273 if (logicalIndex != -1){ 274 name = getLogicalFaceFromFont(fontStyle, logicalIndex); 275 fontStyle = getStyleFromLogicalFace(name); 276 key = name.concat(String.valueOf(size)); 277 } else { 278 name = fontName; 279 key = name.concat(String.valueOf(fontStyle)). 280 concat(String.valueOf(size)); 281 } 282 283 HashMapReference hmr = fontsTable.get(key); 284 if (hmr != null) { 285 peer = hmr.get(); 286 } 287 288 if (peer == null) { 289 peer = createFontPeer(name, fontStyle, size, logicalIndex); 290 if (peer == null){ 291 peer = getFontPeer(DIALOG_NAME, fontStyle, size); 292 } 293 fontsTable.put(key, new HashMapReference(key, peer, queue)); 294 } 295 296 return peer; 297 } 298 299 /** 300 * Returns instance of font peer (logical or physical) according to the 301 * specified parameters. 302 * 303 * @param name font face name 304 * @param style style of the font 305 * @param size size of the font 306 * @param logicalIndex index of the logical face name in LOGICAL_FONT_FACES 307 * array or -1 if desired font peer is not logical. 308 */ 309 private FontPeer createFontPeer(String name, int style, int size, int logicalIndex){ 310 FontPeer peer; 311 if (logicalIndex != -1){ 312 peer = createLogicalFontPeer(name, style, size); 313 }else { 314 peer = createPhysicalFontPeer(name, style, size); 315 } 316 317 return peer; 318 } 319 320 /** 321 * Returns family name for logical face names as a parameter. 322 * 323 * @param faceName logical font face name 324 */ 325 public String getFamilyFromLogicalFace(String faceName){ 326 int pos = faceName.indexOf("."); //$NON-NLS-1$ 327 if (pos == -1){ 328 return faceName; 329 } 330 331 return faceName.substring(0, pos); 332 } 333 334 /** 335 * Returns new logical font peer for the parameters specified using font 336 * properties. 337 * 338 * @param faceName face name of the logical font 339 * @param style style of the font 340 * @param size font size 341 * 342 */ 343 private FontPeer createLogicalFontPeer(String faceName, int style, int size){ 344 String family = getFamilyFromLogicalFace(faceName); 345 FontProperty[] fps = getFontProperties(family.toLowerCase() + "." + style); //$NON-NLS-1$ 346 if (fps != null){ 347 int numFonts = fps.length; 348 FontPeerImpl[] physicalFonts = new FontPeerImpl[numFonts]; 349 for (int i = 0; i < numFonts; i++){ 350 FontProperty fp = fps[i]; 351 352 String name = fp.getName(); 353 int fpStyle = fp.getStyle(); 354 String key = name.concat(String.valueOf(fpStyle)). 355 concat(String.valueOf(size)); 356 357 HashMapReference hmr = fontsTable.get(key); 358 if (hmr != null) { 359 physicalFonts[i] = (FontPeerImpl)hmr.get(); 360 } 361 362 if (physicalFonts[i] == null){ 363 physicalFonts[i] = (FontPeerImpl)createPhysicalFontPeer(name, fpStyle, size); 364 fontsTable.put(key, new HashMapReference(key, physicalFonts[i], queue)); 365 } 366 367 if (physicalFonts[i] == null){ 368 physicalFonts[i] = (FontPeerImpl)getDefaultFont(style, size); 369 } 370 } 371 return new CompositeFont(family, faceName, style, size, fps, physicalFonts); 372 } 373 374 // if there is no property for this logical font - default font is to be 375 // created 376 FontPeerImpl peer = (FontPeerImpl)getDefaultFont(style, size); 377 378 return peer; 379 } 380 381 /** 382 * Returns new physical font peer for the parameters specified using font properties 383 * This method must be overridden by subclasses implementations. 384 * 385 * @param faceName face name or family name of the font 386 * @param style style of the font 387 * @param size font size 388 * 389 */ 390 public abstract FontPeer createPhysicalFontPeer(String name, int style, int size); 391 392 /** 393 * Returns default font peer class with "Default" name that is usually 394 * used when font with specified font names and style doesn't exsist 395 * on a system. 396 * 397 * @param style style of the font 398 * @param size size of the font 399 */ 400 public FontPeer getDefaultFont(int style, int size){ 401 updateFontsTable(); 402 403 FontPeer peer = null; 404 String key = DEFAULT_NAME.concat(String.valueOf(style)). 405 concat(String.valueOf(size)); 406 407 HashMapReference hmr = fontsTable.get(key); 408 if (hmr != null) { 409 peer = hmr.get(); 410 } 411 412 if (peer == null) { 413 peer = createDefaultFont(style, size); 414 415 ((FontPeerImpl)peer).setFamily(DEFAULT_NAME); 416 ((FontPeerImpl)peer).setPSName(DEFAULT_NAME); 417 ((FontPeerImpl)peer).setFontName(DEFAULT_NAME); 418 419 fontsTable.put(key, new HashMapReference(key, peer, queue)); 420 } 421 422 return peer; 423 } 424 425 /** 426 * 427 * Returns new default font peer with "Default" name for the parameters 428 * specified. This method must be overridden by subclasses implementations. 429 * 430 * @param style style of the font 431 * @param size size of the font 432 */ 433 public abstract FontPeer createDefaultFont(int style, int size); 434 435 /** 436 * Returns face name of the logical font, which is the result 437 * of specified font style and face style union. 438 * 439 * @param fontStyle specified style of the font 440 * @param logicalIndex index of the specified face from the 441 * LOGICAL_FONT_FACES array 442 * @return resulting face name 443 */ 444 public String getLogicalFaceFromFont(int fontStyle, int logicalIndex){ 445 int style = 0; 446 String name = LOGICAL_FONT_FACES[logicalIndex]; 447 int pos = name.indexOf("."); //$NON-NLS-1$ 448 449 if (pos == -1){ 450 return createLogicalFace(name, fontStyle); 451 } 452 453 String styleName = name.substring(pos+1); 454 name = name.substring(0, pos); 455 456 // appending font style to the face style 457 style = fontStyle | getLogicalStyle(styleName); 458 459 return createLogicalFace(name, style); 460 } 461 462 /** 463 * Function returns style value from logical face name. 464 * 465 * @param name face name 466 * @return font style 467 */ 468 public int getStyleFromLogicalFace(String name){ 469 int style; 470 int pos = name.indexOf("."); //$NON-NLS-1$ 471 472 if (pos == -1){ 473 return Font.PLAIN; 474 } 475 476 String styleName = name.substring(pos+1); 477 478 style = getLogicalStyle(styleName); 479 480 return style; 481 } 482 483 /** 484 * Returns logical face name corresponding to the logical 485 * family name and style of the font. 486 * 487 * @param family font family 488 * @param styleIndex index of the style name from the STYLE_NAMES array 489 */ 490 public String createLogicalFace(String family, int styleIndex){ 491 return family + "." + STYLE_NAMES[styleIndex]; //$NON-NLS-1$ 492 } 493 494 /** 495 * Return language Id from LCID hash corresponding to the specified locale 496 * 497 * @param l specified locale 498 */ 499 public Short getLCID(Locale l){ 500 if (this.tableLCID.size() == 0){ 501 initLCIDTable(); 502 } 503 504 return tableLCID.get(l.toString()); 505 } 506 507 /** 508 * Platform-dependent LCID table init. 509 */ 510 public abstract void initLCIDTable(); 511 512 /** 513 * Freeing native resources. This hook is used to avoid 514 * sudden application exit and to free resources created in native code. 515 */ 516 private class DisposeNativeHook extends Thread { 517 518 @Override 519 public void run() { 520 try{ 521 /* Disposing native font peer's resources */ 522 Enumeration<String> kEnum = fontsTable.keys(); 523 524 while(kEnum.hasMoreElements()){ 525 Object key = kEnum.nextElement(); 526 HashMapReference hmr = fontsTable.remove(key); 527 FontPeerImpl delPeer = (FontPeerImpl)hmr.get(); 528 529 if ((delPeer != null) && (delPeer.getClass() != CompositeFont.class)){ 530 // there's nothing to dispose in CompositeFont objects 531 delPeer.dispose(); 532 } 533 } 534 } catch (Throwable t){ 535 throw new RuntimeException(t); 536 } 537 } 538 } 539 540 /** 541 * Returns File object, created in a directory 542 * according to the System, where JVM is being ran. 543 * 544 * In Linux case we use ".fonts" directory (for fontconfig purpose), 545 * where font file from the stream will be stored, hence in LinuxFontManager this 546 * method is overridden. 547 * In Windows case we use Windows temp directory (default implementation) 548 * 549 */ 550 public File getTempFontFile()throws IOException{ 551 //???AWT 552 /* 553 File fontFile = File.createTempFile("jFont", ".ttf"); //$NON-NLS-1$ //$NON-NLS-2$ 554 fontFile.deleteOnExit(); 555 556 return fontFile; 557 */ 558 if(NOT_IMP) 559 throw new NotImplementedException("getTempFontFile not Implemented"); 560 return null; 561 } 562 563 /** 564 * Returns File object with font properties. It's name obtained using current 565 * system configuration properties and locale settings. If no appropriate 566 * file is found method returns null. 567 */ 568 public static File getFontPropertyFile(){ 569 File file = null; 570 571 String javaHome = System.getProperty("java.home"); //$NON-NLS-1$ 572 Locale l = Locale.getDefault(); 573 String language = l.getLanguage(); 574 String country = l.getCountry(); 575 String fileEncoding = System.getProperty("file.encoding"); //$NON-NLS-1$ 576 577 String os = System.getProperty("os.name"); //$NON-NLS-1$ 578 579 int i = 0; 580 581 // OS names from system properties don't match 582 // OS identifiers used in font.property files 583 for (; i < OS_VALUES.length; i++){ 584 if (os.endsWith(OS_VALUES[i])){ 585 os = OS_VALUES[i]; 586 break; 587 } 588 } 589 590 if (i == OS_VALUES.length){ 591 os = null; 592 } 593 594 String version = System.getProperty("os.version"); //$NON-NLS-1$ 595 String pathname; 596 597 for (i = 0; i < FP_FILE_NAMES.length; i++){ 598 pathname = FP_FILE_NAMES[i]; 599 if (os != null){ 600 pathname = pathname.replaceFirst("OS", os); //$NON-NLS-1$ 601 } 602 603 pathname = javaHome + pathname; 604 605 pathname = pathname.replaceAll("Language", language). //$NON-NLS-1$ 606 replaceAll("Country", country). //$NON-NLS-1$ 607 replaceAll("Encoding", fileEncoding). //$NON-NLS-1$ 608 replaceAll("Version", version); //$NON-NLS-1$ 609 610 file = new File(pathname); 611 612 if (file.exists()){ 613 break; 614 } 615 } 616 617 return file.exists() ? file : null; 618 } 619 620 /** 621 * Returns an array of integer range values 622 * if the parameter exclusionString has format: 623 * Range 624 * Range [, exclusionString] 625 * 626 * Range: 627 * Char-Char 628 * 629 * Char: 630 * HexDigit HexDigit HexDigit HexDigit 631 * 632 * Method returns null if the specified string is null. 633 * 634 * @param exclusionString string parameter in specified format 635 */ 636 public static int[] parseIntervals(String exclusionString){ 637 int[] results = null; 638 639 if (exclusionString == null){ 640 return null; 641 } 642 643 String[] intervals = exclusionString.split(","); //$NON-NLS-1$ 644 645 if (intervals != null){ 646 int num = intervals.length; 647 if (num > 0){ 648 results = new int[intervals.length << 1]; 649 for (int i = 0; i < intervals.length; i++){ 650 String ranges[] = intervals[i].split("-"); //$NON-NLS-1$ 651 results[i*2] = Integer.parseInt(ranges[0], 16); 652 results[i*2+1] = Integer.parseInt(ranges[1], 16); 653 654 } 655 } 656 } 657 return results; 658 } 659 660 /** 661 * Returns Properties from the properties file or null if 662 * there is an error with FileInputStream processing. 663 * 664 * @param file File object containing properties 665 */ 666 public static Properties getProperties(File file){ 667 Properties props = null; 668 FileInputStream fis = null; 669 try{ 670 fis = new FileInputStream(file); 671 props = new Properties(); 672 props.load(fis); 673 } catch (Exception e){ 674 System.out.println(e); 675 } 676 return props; 677 } 678 679 /** 680 * Returns an array of FontProperties from the properties file 681 * with the specified property name "logical face.style". E.g. 682 * "dialog.2" corresponds to the font family Dialog with bold style. 683 * 684 * @param fpName key of the font properties in the properties set 685 */ 686 public FontProperty[] getFontProperties(String fpName){ 687 Vector<FontProperty> props = fProperties.get(fpName); 688 689 if (props == null){ 690 return null; 691 } 692 693 int size = props.size(); 694 695 if (size == 0){ 696 return null; 697 } 698 699 FontProperty[] fps = new FontProperty[size]; 700 for (int i=0; i < fps.length; i++){ 701 fps[i] = props.elementAt(i); 702 } 703 return fps; 704 } 705 706 /** 707 * Returns index of the font name in array of font names or -1 if 708 * this font is not logical. 709 * 710 * @param fontName specified font name 711 */ 712 public static int getLogicalFaceIndex(String fontName){ 713 for (int i=0; i<LOGICAL_FONT_NAMES.length; i++ ){ 714 if (LOGICAL_FONT_NAMES[i].equalsIgnoreCase(fontName)){ 715 return i; 716 } 717 } 718 return -1; 719 } 720 721 /** 722 * Returns true if specified family name is available in this 723 * GraphicsEnvironment. 724 * 725 * @param familyName the specified font family name 726 */ 727 public boolean isFamilyExist(String familyName){ 728 return (getFamilyIndex(familyName) != -1); 729 } 730 731 /** 732 * Returns index of family name from the array of family names available in 733 * this GraphicsEnvironment or -1 if no family name was found. 734 * 735 * @param familyName specified font family name 736 */ 737 public int getFamilyIndex(String familyName){ 738 for (int i=0; i<allFamilies.length; i++ ){ 739 if (familyName.equalsIgnoreCase(allFamilies[i])){ 740 return i; 741 } 742 } 743 return -1; 744 } 745 746 /** 747 * Returns family with index specified from the array of family names available in 748 * this GraphicsEnvironment. 749 * 750 * @param index index of the family in families names array 751 */ 752 public String getFamily(int index){ 753 return allFamilies[index]; 754 } 755 /** 756 * Returns index of face name from the array of face names available in 757 * this GraphicsEnvironment or -1 if no face name was found. Default return 758 * value is -1, method must be overridden by FontManager implementation. 759 * 760 * @param faceName font face name which index is to be searched 761 */ 762 public int getFaceIndex(String faceName){ 763 return -1; 764 } 765 766 public abstract String[] getAllFamilies(); 767 768 public abstract Font[] getAllFonts(); 769 770 /** 771 * Class contains SoftReference instance that can be stored in the 772 * Hashtable by means of key field corresponding to it. 773 */ 774 private class HashMapReference extends SoftReference<FontPeer> { 775 776 /** 777 * The key for Hashtable. 778 */ 779 private final String key; 780 781 /** 782 * Creates a new soft reference with the key specified and 783 * adding this reference in the reference queue specified. 784 * 785 * @param key the key in Hashtable 786 * @param value object that corresponds to the key 787 * @param queue reference queue where reference is to be added 788 */ 789 public HashMapReference(final String key, final FontPeer value, 790 final ReferenceQueue<FontPeer> queue) { 791 super(value, queue); 792 this.key = key; 793 } 794 795 /** 796 * Returns the key that corresponds to the SoftReference instance 797 * 798 * @return the key in Hashtable with cached references 799 */ 800 public Object getKey() { 801 return key; 802 } 803 } 804 805 /** 806 * Removes keys from the Hashtable with font peers which corresponding 807 * HashMapReference objects were garbage collected. 808 */ 809 private void updateFontsTable() { 810 HashMapReference r; 811 //???AWT 812 //while ((r = (HashMapReference)queue.poll()) != null) { 813 // fontsTable.remove(r.getKey()); 814 //} 815 } 816 817 } 818 819 820