Mercurial > projects > dwt2
comparison org.eclipse.jface/src/org/eclipse/jface/resource/FontRegistry.d @ 12:bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 14 Mar 2009 18:23:29 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
11:43904fec5dca | 12:bc29606a740c |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2008 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module org.eclipse.jface.resource.FontRegistry; | |
14 | |
15 import org.eclipse.jface.resource.ResourceRegistry; | |
16 import org.eclipse.jface.resource.FontDescriptor; | |
17 import org.eclipse.jface.resource.StringConverter; | |
18 import org.eclipse.jface.resource.JFaceResources; | |
19 import org.eclipse.jface.resource.DataFormatException; | |
20 | |
21 import org.eclipse.swt.SWT; | |
22 import org.eclipse.swt.graphics.Font; | |
23 import org.eclipse.swt.graphics.FontData; | |
24 import org.eclipse.swt.widgets.Display; | |
25 import org.eclipse.swt.widgets.Shell; | |
26 import org.eclipse.core.runtime.Assert; | |
27 | |
28 import java.util.ResourceBundle; | |
29 import java.util.MissingResourceException; | |
30 import java.lang.all; | |
31 import java.util.Collections; | |
32 import java.util.Collection; | |
33 import java.util.List; | |
34 import java.util.ArrayList; | |
35 import java.util.Iterator; | |
36 import java.util.Map; | |
37 import java.util.HashMap; | |
38 import java.util.Set; | |
39 version(Windows) import org.eclipse.swt.internal.win32.OS; | |
40 | |
41 /** | |
42 * A font registry maintains a mapping between symbolic font names | |
43 * and SWT fonts. | |
44 * <p> | |
45 * A font registry owns all of the font objects registered | |
46 * with it, and automatically disposes of them when the SWT Display | |
47 * that creates the fonts is disposed. Because of this, clients do | |
48 * not need to (indeed, must not attempt to) dispose of font | |
49 * objects themselves. | |
50 * </p> | |
51 * <p> | |
52 * A special constructor is provided for populating a font registry | |
53 * from a property files using the standard Java resource bundle mechanism. | |
54 * </p> | |
55 * <p> | |
56 * Methods are provided for registering listeners that will be kept | |
57 * apprised of changes to list of registed fonts. | |
58 * </p> | |
59 * <p> | |
60 * Clients may instantiate this class (it was not designed to be subclassed). | |
61 * </p> | |
62 * | |
63 * Since 3.0 this class extends ResourceRegistry. | |
64 * @noextend This class is not intended to be subclassed by clients. | |
65 */ | |
66 public class FontRegistry : ResourceRegistry { | |
67 | |
68 /** | |
69 * FontRecord is a private helper class that holds onto a font | |
70 * and can be used to generate its bold and italic version. | |
71 */ | |
72 private class FontRecord { | |
73 | |
74 Font baseFont; | |
75 | |
76 Font boldFont; | |
77 | |
78 Font italicFont; | |
79 | |
80 FontData[] baseData; | |
81 | |
82 /** | |
83 * Create a new instance of the receiver based on the | |
84 * plain font and the data for it. | |
85 * @param plainFont The base looked up font. | |
86 * @param data The data used to look it up. | |
87 */ | |
88 this(Font plainFont, FontData[] data) { | |
89 baseFont = plainFont; | |
90 baseData = data; | |
91 } | |
92 | |
93 /** | |
94 * Dispose any of the fonts created for this record. | |
95 */ | |
96 void dispose() { | |
97 baseFont.dispose(); | |
98 if (boldFont !is null) { | |
99 boldFont.dispose(); | |
100 } | |
101 if (italicFont !is null) { | |
102 italicFont.dispose(); | |
103 } | |
104 } | |
105 | |
106 /** | |
107 * Return the base Font. | |
108 * @return Font | |
109 */ | |
110 public Font getBaseFont() { | |
111 return baseFont; | |
112 } | |
113 | |
114 /** | |
115 * Return the bold Font. Create a bold version | |
116 * of the base font to get it. | |
117 * @return Font | |
118 */ | |
119 public Font getBoldFont() { | |
120 if (boldFont !is null) { | |
121 return boldFont; | |
122 } | |
123 | |
124 FontData[] boldData = getModifiedFontData(SWT.BOLD); | |
125 boldFont = new Font(Display.getCurrent(), boldData); | |
126 return boldFont; | |
127 } | |
128 | |
129 /** | |
130 * Get a version of the base font data with the specified | |
131 * style. | |
132 * @param style the new style | |
133 * @return the font data with the style {@link FontData#FontData(String, int, int)} | |
134 * @see SWT#ITALIC | |
135 * @see SWT#NORMAL | |
136 * @see SWT#BOLD | |
137 * @todo Generated comment | |
138 */ | |
139 private FontData[] getModifiedFontData(int style) { | |
140 FontData[] styleData = new FontData[baseData.length]; | |
141 for (int i = 0; i < styleData.length; i++) { | |
142 FontData base = baseData[i]; | |
143 styleData[i] = new FontData(base.getName(), base.getHeight(), | |
144 base.getStyle() | style); | |
145 } | |
146 | |
147 return styleData; | |
148 } | |
149 | |
150 /** | |
151 * Return the italic Font. Create an italic version of the | |
152 * base font to get it. | |
153 * @return Font | |
154 */ | |
155 public Font getItalicFont() { | |
156 if (italicFont !is null) { | |
157 return italicFont; | |
158 } | |
159 | |
160 FontData[] italicData = getModifiedFontData(SWT.ITALIC); | |
161 italicFont = new Font(Display.getCurrent(), italicData); | |
162 return italicFont; | |
163 } | |
164 | |
165 /** | |
166 * Add any fonts that were allocated for this record to the | |
167 * stale fonts. Anything that matches the default font will | |
168 * be skipped. | |
169 * @param defaultFont The system default. | |
170 */ | |
171 void addAllocatedFontsToStale(Font defaultFont) { | |
172 //Return all of the fonts allocated by the receiver. | |
173 //if any of them are the defaultFont then don't bother. | |
174 if (defaultFont !is baseFont && baseFont !is null) { | |
175 staleFonts.add(baseFont); | |
176 } | |
177 if (defaultFont !is boldFont && boldFont !is null) { | |
178 staleFonts.add(boldFont); | |
179 } | |
180 if (defaultFont !is italicFont && italicFont !is null) { | |
181 staleFonts.add(italicFont); | |
182 } | |
183 } | |
184 } | |
185 | |
186 /** | |
187 * Table of known fonts, keyed by symbolic font name | |
188 * (key type: <code>String</code>, | |
189 * value type: <code>FontRecord</code>. | |
190 */ | |
191 private Map stringToFontRecord; | |
192 | |
193 /** | |
194 * Table of known font data, keyed by symbolic font name | |
195 * (key type: <code>String</code>, | |
196 * value type: <code>org.eclipse.swt.graphics.FontData[]</code>). | |
197 */ | |
198 private Map stringToFontData; | |
199 | |
200 /** | |
201 * Collection of Fonts that are now stale to be disposed | |
202 * when it is safe to do so (i.e. on shutdown). | |
203 * @see List | |
204 */ | |
205 private List staleFonts; | |
206 | |
207 /** | |
208 * Runnable that cleans up the manager on disposal of the display. | |
209 */ | |
210 protected Runnable displayRunnable; | |
211 | |
212 private bool displayDisposeHooked; | |
213 | |
214 private final bool cleanOnDisplayDisposal; | |
215 | |
216 /** | |
217 * Creates an empty font registry. | |
218 * <p> | |
219 * There must be an SWT Display created in the current | |
220 * thread before calling this method. | |
221 * </p> | |
222 */ | |
223 public this() { | |
224 this(Display.getCurrent(), true); | |
225 } | |
226 | |
227 /** | |
228 * Creates a font registry and initializes its content from | |
229 * a property file. | |
230 * <p> | |
231 * There must be an SWT Display created in the current | |
232 * thread before calling this method. | |
233 * </p> | |
234 * <p> | |
235 * The OS name (retrieved using <code>System.getProperty("os.name")</code>) | |
236 * is converted to lowercase, purged of whitespace, and appended | |
237 * as suffix (separated by an underscore <code>'_'</code>) to the given | |
238 * location string to yield the base name of a resource bundle | |
239 * acceptable to <code>ResourceBundle.getBundle</code>. | |
240 * The standard Java resource bundle mechanism is then used to locate | |
241 * and open the appropriate properties file, taking into account | |
242 * locale specific variations. | |
243 * </p> | |
244 * <p> | |
245 * For example, on the Windows 2000 operating system the location string | |
246 * <code>"com.example.myapp.Fonts"</code> yields the base name | |
247 * <code>"com.example.myapp.Fonts_windows2000"</code>. For the US English locale, | |
248 * this further elaborates to the resource bundle name | |
249 * <code>"com.example.myapp.Fonts_windows2000_en_us"</code>. | |
250 * </p> | |
251 * <p> | |
252 * If no appropriate OS-specific resource bundle is found, the | |
253 * process is repeated using the location as the base bundle name. | |
254 * </p> | |
255 * <p> | |
256 * The property file contains entries that look like this: | |
257 * <pre> | |
258 * textfont.0=MS Sans Serif-regular-10 | |
259 * textfont.1=Times New Roman-regular-10 | |
260 * | |
261 * titlefont.0=MS Sans Serif-regular-12 | |
262 * titlefont.1=Times New Roman-regular-12 | |
263 * </pre> | |
264 * Each entry maps a symbolic font names (the font registry keys) with | |
265 * a "<code>.<it>n</it></code> suffix to standard font names | |
266 * on the right. The suffix indicated order of preference: | |
267 * "<code>.0</code>" indicates the first choice, | |
268 * "<code>.1</code>" indicates the second choice, and so on. | |
269 * </p> | |
270 * The following example shows how to use the font registry: | |
271 * <pre> | |
272 * FontRegistry registry = new FontRegistry("com.example.myapp.fonts"); | |
273 * Font font = registry.get("textfont"); | |
274 * control.setFont(font); | |
275 * ... | |
276 * </pre> | |
277 * | |
278 * @param location the name of the resource bundle | |
279 * @param loader the ClassLoader to use to find the resource bundle | |
280 * @exception MissingResourceException if the resource bundle cannot be found | |
281 * @since 2.1 | |
282 */ | |
283 public this(String location, /+ClassLoader+/Object loader){ | |
284 initInstance(); | |
285 Display display = Display.getCurrent(); | |
286 Assert.isNotNull(display); | |
287 // FIXE: need to respect loader | |
288 //readResourceBundle(location, loader); | |
289 readResourceBundle(location); | |
290 | |
291 cleanOnDisplayDisposal = true; | |
292 hookDisplayDispose(display); | |
293 } | |
294 | |
295 private void initInstance(){ | |
296 displayRunnable = new class Runnable { | |
297 public void run() { | |
298 clearCaches(); | |
299 } | |
300 }; | |
301 stringToFontRecord = new HashMap(7); | |
302 stringToFontData = new HashMap(7); | |
303 staleFonts = new ArrayList(); | |
304 } | |
305 | |
306 /** | |
307 * Load the FontRegistry using the ClassLoader from the PlatformUI | |
308 * plug-in | |
309 * @param location the location to read the resource bundle from | |
310 * @throws MissingResourceException Thrown if a resource is missing | |
311 */ | |
312 public this(String location) { | |
313 // FIXE: | |
314 // this(location, WorkbenchPlugin.getDefault().getDescriptor().getPluginClassLoader()); | |
315 this(location, null); | |
316 } | |
317 | |
318 /** | |
319 * Read the resource bundle at location. Look for a file with the | |
320 * extension _os_ws first, then _os then just the name. | |
321 * @param location - String - the location of the file. | |
322 */ | |
323 | |
324 private void readResourceBundle(String location) { | |
325 // String osname = System.getProperty("os.name").trim(); //$NON-NLS-1$ | |
326 // String wsname = SWT.getPlatform(); | |
327 // osname = StringConverter.removeWhiteSpaces(osname).toLowerCase(); | |
328 // wsname = StringConverter.removeWhiteSpaces(wsname).toLowerCase(); | |
329 // String OSLocation = location; | |
330 // String WSLocation = location; | |
331 ResourceBundle bundle = null; | |
332 // if (osname !is null) { | |
333 // OSLocation = location ~ "_" ~ osname; //$NON-NLS-1$ | |
334 // if (wsname !is null) { | |
335 // WSLocation = OSLocation ~ "_" ~ wsname; //$NON-NLS-1$ | |
336 // } | |
337 // } | |
338 String errorLocation = "org.eclipse.jface.resource.FontRegistry properties"; | |
339 const char[] prefix = "org.eclipse.jface.resource.jfacefonts_"; | |
340 const char[] postfix = ".properties"; | |
341 version( linux ){ | |
342 ImportData propdata = getImportData!( prefix ~ "linux_gtk" ~ postfix ); | |
343 } | |
344 else version( Windows ){ | |
345 ImportData propdata; | |
346 if( OS.IsWin95 && OS.WIN32_VERSION >= OS.VERSION (4, 10 )){ | |
347 propdata = getImportData!( prefix ~ "windows98" ~ postfix ); | |
348 } | |
349 else if( OS.WIN32_VERSION >= OS.VERSION (5, 1 )){ | |
350 propdata = getImportData!( prefix ~ "windowsxp" ~ postfix ); | |
351 } | |
352 else if( OS.WIN32_VERSION >= OS.VERSION (5, 0)){ | |
353 propdata = getImportData!( prefix ~ "windows2000" ~ postfix ); | |
354 } | |
355 else if( OS.WIN32_VERSION >= OS.VERSION (4, 0)){ | |
356 propdata = getImportData!( prefix ~ "windowsnt" ~ postfix ); | |
357 } | |
358 else{ | |
359 assert( false, "TODO: detect windows version" ); | |
360 } | |
361 } | |
362 else { | |
363 static assert( false, "unknown plattform" ); | |
364 } | |
365 | |
366 // try { | |
367 bundle = ResourceBundle.getBundle(propdata); | |
368 readResourceBundle(bundle, errorLocation); | |
369 // } catch (MissingResourceException wsException) { | |
370 // try { | |
371 // bundle = ResourceBundle.getBundle(OSLocation); | |
372 // readResourceBundle(bundle, WSLocation); | |
373 // } catch (MissingResourceException osException) { | |
374 // if (location !is OSLocation) { | |
375 // bundle = ResourceBundle.getBundle(location); | |
376 // readResourceBundle(bundle, WSLocation); | |
377 // } else { | |
378 // throw osException; | |
379 // } | |
380 // } | |
381 // } | |
382 } | |
383 | |
384 /** | |
385 * Creates an empty font registry. | |
386 * | |
387 * @param display the Display | |
388 */ | |
389 public this(Display display) { | |
390 this(display, true); | |
391 } | |
392 | |
393 /** | |
394 * Creates an empty font registry. | |
395 * | |
396 * @param display | |
397 * the <code>Display</code> | |
398 * @param cleanOnDisplayDisposal | |
399 * whether all fonts allocated by this <code>FontRegistry</code> | |
400 * should be disposed when the display is disposed | |
401 * @since 3.1 | |
402 */ | |
403 public this(Display display, bool cleanOnDisplayDisposal) { | |
404 initInstance(); | |
405 Assert.isNotNull(display); | |
406 this.cleanOnDisplayDisposal = cleanOnDisplayDisposal; | |
407 if (cleanOnDisplayDisposal) { | |
408 hookDisplayDispose(display); | |
409 } | |
410 } | |
411 | |
412 /** | |
413 * Find the first valid fontData in the provided list. If none are valid | |
414 * return the first one regardless. If the list is empty return null. Return | |
415 * <code>null</code> if one cannot be found. | |
416 * | |
417 * @param fonts the font list | |
418 * @param display the display used | |
419 * @return the font data of the like describe above | |
420 * | |
421 * @deprecated use bestDataArray in order to support Motif multiple entry | |
422 * fonts. | |
423 */ | |
424 public FontData bestData(FontData[] fonts, Display display) { | |
425 for (int i = 0; i < fonts.length; i++) { | |
426 FontData fd = fonts[i]; | |
427 | |
428 if (fd is null) { | |
429 break; | |
430 } | |
431 | |
432 FontData[] fixedFonts = display.getFontList(fd.getName(), false); | |
433 if (isFixedFont(fixedFonts, fd)) { | |
434 return fd; | |
435 } | |
436 | |
437 FontData[] scalableFonts = display.getFontList(fd.getName(), true); | |
438 if (scalableFonts.length > 0) { | |
439 return fd; | |
440 } | |
441 } | |
442 | |
443 //None of the provided datas are valid. Return the | |
444 //first one as it is at least the first choice. | |
445 if (fonts.length > 0) { | |
446 return fonts[0]; | |
447 } | |
448 | |
449 //Nothing specified | |
450 return null; | |
451 } | |
452 | |
453 /** | |
454 * Find the first valid fontData in the provided list. | |
455 * If none are valid return the first one regardless. | |
456 * If the list is empty return <code>null</code>. | |
457 * | |
458 * @param fonts list of fonts | |
459 * @param display the display | |
460 * @return font data like described above | |
461 * @deprecated use filterData in order to preserve | |
462 * multiple entry fonts on Motif | |
463 */ | |
464 public FontData[] bestDataArray(FontData[] fonts, Display display) { | |
465 | |
466 FontData bestData = bestData(fonts, display); | |
467 if (bestData is null) { | |
468 return null; | |
469 } | |
470 | |
471 FontData[] datas = new FontData[1]; | |
472 datas[0] = bestData; | |
473 return datas; | |
474 } | |
475 | |
476 /** | |
477 * Removes from the list all fonts that do not exist in this system. | |
478 * If none are valid, return the first irregardless. If the list is | |
479 * empty return <code>null</code>. | |
480 * | |
481 * @param fonts the fonts to check | |
482 * @param display the display to check against | |
483 * @return the list of fonts that have been found on this system | |
484 * @since 3.1 | |
485 */ | |
486 public FontData [] filterData(FontData [] fonts, Display display) { | |
487 ArrayList good = new ArrayList(fonts.length); | |
488 for (int i = 0; i < fonts.length; i++) { | |
489 FontData fd = fonts[i]; | |
490 | |
491 if (fd is null) { | |
492 continue; | |
493 } | |
494 | |
495 FontData[] fixedFonts = display.getFontList(fd.getName(), false); | |
496 if (isFixedFont(fixedFonts, fd)) { | |
497 good.add(fd); | |
498 } | |
499 | |
500 FontData[] scalableFonts = display.getFontList(fd.getName(), true); | |
501 if (scalableFonts.length > 0) { | |
502 good.add(fd); | |
503 } | |
504 } | |
505 | |
506 | |
507 //None of the provided datas are valid. Return the | |
508 //first one as it is at least the first choice. | |
509 if (good.isEmpty() && fonts.length > 0) { | |
510 good.add(fonts[0]); | |
511 } | |
512 else if (fonts.length is 0) { | |
513 return null; | |
514 } | |
515 | |
516 return arraycast!(FontData)(good.toArray()); | |
517 } | |
518 | |
519 | |
520 /** | |
521 * Creates a new font with the given font datas or <code>null</code> | |
522 * if there is no data. | |
523 * @return FontRecord for the new Font or <code>null</code>. | |
524 */ | |
525 private FontRecord createFont(String symbolicName, FontData[] fonts) { | |
526 Display display = Display.getCurrent(); | |
527 if (display is null) { | |
528 return null; | |
529 } | |
530 if (cleanOnDisplayDisposal && !displayDisposeHooked) { | |
531 hookDisplayDispose(display); | |
532 } | |
533 | |
534 FontData[] validData = filterData(fonts, display); | |
535 if (validData.length is 0) { | |
536 //Nothing specified | |
537 return null; | |
538 } | |
539 | |
540 //Do not fire the update from creation as it is not a property change | |
541 put(symbolicName, validData, false); | |
542 Font newFont = new Font(display, validData); | |
543 return new FontRecord(newFont, validData); | |
544 } | |
545 | |
546 /** | |
547 * Calculates the default font and returns the result. | |
548 * This method creates a font that must be disposed. | |
549 */ | |
550 Font calculateDefaultFont() { | |
551 Display current = Display.getCurrent(); | |
552 if (current is null) { | |
553 Shell shell = new Shell(); | |
554 Font font = new Font(null, shell.getFont().getFontData()); | |
555 shell.dispose(); | |
556 return font; | |
557 } | |
558 return new Font(current, current.getSystemFont().getFontData()); | |
559 } | |
560 | |
561 /** | |
562 * Returns the default font data. Creates it if necessary. | |
563 * @return Font | |
564 */ | |
565 public Font defaultFont() { | |
566 return defaultFontRecord().getBaseFont(); | |
567 } | |
568 | |
569 /** | |
570 * Returns the font descriptor for the font with the given symbolic | |
571 * font name. Returns the default font if there is no special value | |
572 * associated with that name | |
573 * | |
574 * @param symbolicName symbolic font name | |
575 * @return the font descriptor (never null) | |
576 * | |
577 * @since 3.3 | |
578 */ | |
579 public FontDescriptor getDescriptor(String symbolicName) { | |
580 Assert.isTrue(symbolicName.length > 0); | |
581 return FontDescriptor.createFrom(getFontData(symbolicName)); | |
582 } | |
583 | |
584 | |
585 | |
586 /** | |
587 * Returns the default font record. | |
588 */ | |
589 private FontRecord defaultFontRecord() { | |
590 | |
591 FontRecord record = cast(FontRecord) stringToFontRecord | |
592 .get(JFaceResources.DEFAULT_FONT); | |
593 if (record is null) { | |
594 Font defaultFont = calculateDefaultFont(); | |
595 record = createFont(JFaceResources.DEFAULT_FONT, defaultFont | |
596 .getFontData()); | |
597 defaultFont.dispose(); | |
598 stringToFontRecord.put(stringcast(JFaceResources.DEFAULT_FONT), record); | |
599 } | |
600 return record; | |
601 } | |
602 | |
603 /** | |
604 * Returns the default font data. Creates it if necessary. | |
605 */ | |
606 private FontData[] defaultFontData() { | |
607 return defaultFontRecord().baseData; | |
608 } | |
609 | |
610 /** | |
611 * Returns the font data associated with the given symbolic font name. | |
612 * Returns the default font data if there is no special value associated | |
613 * with that name. | |
614 * | |
615 * @param symbolicName symbolic font name | |
616 * @return the font | |
617 */ | |
618 public FontData[] getFontData(String symbolicName) { | |
619 | |
620 Assert.isTrue(symbolicName.length > 0); | |
621 Object result = stringToFontData.get(symbolicName); | |
622 if (result is null) { | |
623 return defaultFontData(); | |
624 } | |
625 | |
626 return arrayFromObject!(FontData)(result); | |
627 } | |
628 | |
629 /** | |
630 * Returns the font associated with the given symbolic font name. | |
631 * Returns the default font if there is no special value associated | |
632 * with that name. | |
633 * | |
634 * @param symbolicName symbolic font name | |
635 * @return the font | |
636 */ | |
637 public Font get(String symbolicName) { | |
638 | |
639 return getFontRecord(symbolicName).getBaseFont(); | |
640 } | |
641 | |
642 /** | |
643 * Returns the bold font associated with the given symbolic font name. | |
644 * Returns the bolded default font if there is no special value associated | |
645 * with that name. | |
646 * | |
647 * @param symbolicName symbolic font name | |
648 * @return the font | |
649 * @since 3.0 | |
650 */ | |
651 public Font getBold(String symbolicName) { | |
652 | |
653 return getFontRecord(symbolicName).getBoldFont(); | |
654 } | |
655 | |
656 /** | |
657 * Returns the italic font associated with the given symbolic font name. | |
658 * Returns the italic default font if there is no special value associated | |
659 * with that name. | |
660 * | |
661 * @param symbolicName symbolic font name | |
662 * @return the font | |
663 * @since 3.0 | |
664 */ | |
665 public Font getItalic(String symbolicName) { | |
666 | |
667 return getFontRecord(symbolicName).getItalicFont(); | |
668 } | |
669 | |
670 /** | |
671 * Return the font record for the key. | |
672 * @param symbolicName The key for the record. | |
673 * @return FontRecird | |
674 */ | |
675 private FontRecord getFontRecord(String symbolicName) { | |
676 Assert.isNotNull(symbolicName); | |
677 auto result = stringToFontRecord.get(symbolicName); | |
678 if (result !is null) { | |
679 return cast(FontRecord) result; | |
680 } | |
681 | |
682 result = stringToFontData.get(symbolicName); | |
683 | |
684 FontRecord fontRecord; | |
685 | |
686 if (result is null) { | |
687 fontRecord = defaultFontRecord(); | |
688 } else { | |
689 fontRecord = createFont(symbolicName, arrayFromObject!(FontData)(result)); | |
690 } | |
691 | |
692 if (fontRecord is null) { | |
693 fontRecord = defaultFontRecord(); | |
694 } | |
695 | |
696 stringToFontRecord.put(symbolicName.dup, fontRecord); | |
697 return fontRecord; | |
698 | |
699 } | |
700 | |
701 /* (non-Javadoc) | |
702 * @see org.eclipse.jface.resource.ResourceRegistry#getKeySet() | |
703 */ | |
704 public override Set getKeySet() { | |
705 return Collections.unmodifiableSet(stringToFontData.keySet()); | |
706 } | |
707 | |
708 /* (non-Javadoc) | |
709 * @see org.eclipse.jface.resource.ResourceRegistry#hasValueFor(java.lang.String) | |
710 */ | |
711 public override bool hasValueFor(String fontKey) { | |
712 return stringToFontData.containsKey(fontKey); | |
713 } | |
714 | |
715 /* (non-Javadoc) | |
716 * @see org.eclipse.jface.resource.ResourceRegistry#clearCaches() | |
717 */ | |
718 protected override void clearCaches() { | |
719 | |
720 Iterator iterator = stringToFontRecord.values().iterator(); | |
721 while (iterator.hasNext()) { | |
722 Object next = iterator.next(); | |
723 (cast(FontRecord) next).dispose(); | |
724 } | |
725 | |
726 disposeFonts(staleFonts.iterator()); | |
727 stringToFontRecord.clear(); | |
728 staleFonts.clear(); | |
729 | |
730 displayDisposeHooked = false; | |
731 } | |
732 | |
733 /** | |
734 * Dispose of all of the fonts in this iterator. | |
735 * @param iterator over Collection of Font | |
736 */ | |
737 private void disposeFonts(Iterator iterator) { | |
738 while (iterator.hasNext()) { | |
739 Object next = iterator.next(); | |
740 (cast(Font) next).dispose(); | |
741 } | |
742 } | |
743 | |
744 /** | |
745 * Hook a dispose listener on the SWT display. | |
746 */ | |
747 private void hookDisplayDispose(Display display) { | |
748 displayDisposeHooked = true; | |
749 display.disposeExec(displayRunnable); | |
750 } | |
751 | |
752 /** | |
753 * Checks whether the given font is in the list of fixed fonts. | |
754 */ | |
755 private bool isFixedFont(FontData[] fixedFonts, FontData fd) { | |
756 // Can't use FontData.equals() since some values aren't | |
757 // set if a fontdata isn't used. | |
758 int height = fd.getHeight(); | |
759 String name = fd.getName(); | |
760 for (int i = 0; i < fixedFonts.length; i++) { | |
761 FontData fixed = fixedFonts[i]; | |
762 if (fixed.getHeight() is height && fixed.getName().equals(name)) { | |
763 return true; | |
764 } | |
765 } | |
766 return false; | |
767 } | |
768 | |
769 /** | |
770 * Converts a String into a FontData object. | |
771 */ | |
772 private FontData makeFontData(String value) { | |
773 try { | |
774 return StringConverter.asFontData(value.trim()); | |
775 } catch (DataFormatException e) { | |
776 throw new MissingResourceException( | |
777 "Wrong font data format. Value is: \"" ~ value ~ "\"", this.classinfo.name, value); //$NON-NLS-2$//$NON-NLS-1$ | |
778 } | |
779 } | |
780 | |
781 /** | |
782 * Adds (or replaces) a font to this font registry under the given | |
783 * symbolic name. | |
784 * <p> | |
785 * A property change event is reported whenever the mapping from | |
786 * a symbolic name to a font changes. The source of the event is | |
787 * this registry; the property name is the symbolic font name. | |
788 * </p> | |
789 * | |
790 * @param symbolicName the symbolic font name | |
791 * @param fontData an Array of FontData | |
792 */ | |
793 public void put(String symbolicName, FontData[] fontData) { | |
794 put(symbolicName, fontData, true); | |
795 } | |
796 | |
797 /** | |
798 * Adds (or replaces) a font to this font registry under the given | |
799 * symbolic name. | |
800 * <p> | |
801 * A property change event is reported whenever the mapping from | |
802 * a symbolic name to a font changes. The source of the event is | |
803 * this registry; the property name is the symbolic font name. | |
804 * </p> | |
805 * | |
806 * @param symbolicName the symbolic font name | |
807 * @param fontData an Array of FontData | |
808 * @param update - fire a font mapping changed if true. False | |
809 * if this method is called from the get method as no setting | |
810 * has changed. | |
811 */ | |
812 private void put(String symbolicName, FontData[] fontData, bool update) { | |
813 | |
814 Assert.isNotNull(symbolicName); | |
815 Assert.isTrue(fontData.length > 0 ); | |
816 | |
817 FontData[] existing = arrayFromObject!(FontData)( stringToFontData.get(stringcast(symbolicName))); | |
818 if (ArrayEquals(existing, fontData)) { | |
819 return; | |
820 } | |
821 | |
822 FontRecord oldFont = cast(FontRecord) stringToFontRecord.remove(stringcast(symbolicName)); | |
823 stringToFontData.put(symbolicName.dup, new ArrayWrapperObject(fontData)); | |
824 if (update) { | |
825 fireMappingChanged(symbolicName, new ArrayWrapperT!(FontData)(existing), new ArrayWrapperObject(arraycast!(Object)(fontData))); | |
826 } | |
827 | |
828 if (oldFont !is null) { | |
829 oldFont.addAllocatedFontsToStale(defaultFontRecord().getBaseFont()); | |
830 } | |
831 } | |
832 | |
833 /** | |
834 * Reads the resource bundle. This puts FontData[] objects | |
835 * in the mapping table. These will lazily be turned into | |
836 * real Font objects when requested. | |
837 */ | |
838 private void readResourceBundle(ResourceBundle bundle, String bundleName) { | |
839 auto keys = bundle.getKeys(); | |
840 foreach ( key; keys ) { | |
841 int pos = key.lastIndexOf('.'); | |
842 if (pos is -1) { | |
843 stringToFontData.put(stringcast(key.dup), new ArrayWrapperObject(arraycast!(Object)([ makeFontData(bundle | |
844 .getString(key)) ]))); | |
845 } else { | |
846 String name = key.substring(0, pos); | |
847 int i = 0; | |
848 try { | |
849 i = tango.text.convert.Integer.toInt(key.substring(pos + 1)); | |
850 } catch (IllegalArgumentException e) { | |
851 //Panic the file can not be parsed. | |
852 throw new MissingResourceException( | |
853 "Wrong key format ", bundleName, key); //$NON-NLS-1$ | |
854 } | |
855 FontData[] elements = arrayFromObject!(FontData)( stringToFontData.get(stringcast(name))); | |
856 if (elements is null) { | |
857 elements = new FontData[8]; | |
858 stringToFontData.put(name.dup, new ArrayWrapperObject(elements)); | |
859 } | |
860 if (i > elements.length) { | |
861 FontData[] na = new FontData[i + 8]; | |
862 System.arraycopy(elements, 0, na, 0, elements.length); | |
863 elements = na; | |
864 stringToFontData.put(name.dup, new ArrayWrapperObject(elements)); | |
865 } | |
866 elements[i] = makeFontData(bundle.getString(key)); | |
867 } | |
868 } | |
869 } | |
870 | |
871 /** | |
872 * Returns the font descriptor for the JFace default font. | |
873 * | |
874 * @return the font descriptor for the JFace default font | |
875 * @since 3.3 | |
876 */ | |
877 public FontDescriptor defaultFontDescriptor() { | |
878 return FontDescriptor.createFrom(defaultFontData()); | |
879 } | |
880 } |