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