source: trunk/src/org/expeditee/gio/swing/SwingFontManager.java@ 1571

Last change on this file since 1571 was 1571, checked in by davidb, 9 months ago

More nuanced check for loading in a True-type font

File size: 5.9 KB
Line 
1package org.expeditee.gio.swing;
2
3import java.awt.GraphicsEnvironment;
4import java.io.File;
5import java.util.HashMap;
6import java.util.HashSet;
7
8import org.expeditee.core.Font;
9import org.expeditee.gio.FontManager;
10
11/**
12 * The font manager for a Swing system.
13 *
14 * @author cts16
15 */
16public class SwingFontManager extends FontManager {
17
18 private static final String DEFAULT_SWING_FONT = DEFAULT_FONT_FAMILY + "-Plain-" + DEFAULT_FONT_SIZE;
19
20 /** Singleton instance. */
21 private static SwingFontManager _instance = null;
22
23 private static HashMap<String,String> _font_name_lookup = null;
24
25
26 /** Singleton instantiator. */
27 public static SwingFontManager getInstance()
28 {
29 if (_instance == null) _instance = new SwingFontManager();
30
31 if (_font_name_lookup == null) {
32 _font_name_lookup = new HashMap<String,String>();
33
34 java.awt.Font [] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
35
36 for (int i=0; i<fonts.length; i++) {
37 java.awt.Font font = fonts[i];
38 String font_name = font.getFontName();
39 String font_family = font.getFamily();
40
41 // Instead of String->Integer hashmap, let's choose to store the
42 // font family name, in case this is useful at a later point elsewhere
43 _font_name_lookup.put(font_name,font_family);
44 }
45 }
46
47 return _instance;
48 }
49
50 /** Mapping from handles to internal fonts. */
51 private HashMap<Font, java.awt.Font> _fontMap;
52 /** The font family names registered with the manager. */
53 private HashSet<String> _fontNames;
54
55 /** Private constructor for singleton instance. */
56 private SwingFontManager()
57 {
58 // Initialise the font map
59 _fontMap = new HashMap<Font, java.awt.Font>();
60
61 // Initialise the set of family names
62 _fontNames = new HashSet<String>();
63
64 // Initialise default font to Swing default
65 setDefaultFont(register(java.awt.Font.decode(DEFAULT_SWING_FONT)));
66
67 // Add Swing standard fonts to registered fonts
68 registerSwingStandardFonts();// TODO: Reinstate. cts16
69 }
70
71 @Override
72 public Font registerFontFile(File fontFile)
73 {
74 if (fontFile == null) return null;
75
76 java.awt.Font swingFont = null;
77 boolean registerOkay = true;
78
79 // Create the internal font from the given file
80 try {
81 swingFont = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, fontFile);
82 if (swingFont == null) registerOkay = false;
83 } catch (Exception e) {
84 System.err.println("Warning: createFont() failed for:\n " + fontFile.toString());
85 e.printStackTrace();
86 registerOkay = false;
87 }
88
89 // Register the new font with the Swing system
90 if (registerOkay) {
91 registerOkay = GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(swingFont);
92 }
93
94 // Register the new font with ourselves
95 if (registerOkay) {
96 return register(swingFont).clone();
97 }
98 else {
99 // One reason for failing to register is that it already exists
100
101 if (swingFont != null) {
102 String font_name = swingFont.getFontName();
103
104 Boolean font_already_registered = (_font_name_lookup.get(font_name) != null);
105
106 // Loading font was OK after all, just that the JDK already has it
107 if (font_already_registered) {
108 return register(swingFont).clone();
109 }
110 else {
111 System.err.println("Error: failed to register font '" + font_name + "'");
112 }
113 }
114 }
115
116
117 return null;
118 }
119
120 @Override
121 public String[] getRegisteredFontFamilies() {
122
123 return _fontNames.toArray(new String[_fontNames.size()]);
124 }
125
126 @Override
127 public boolean isFontFamilyRegistered(String fontFamily)
128 {
129 return _fontNames.contains(fontFamily);
130 }
131
132 @Override
133 public Font getActualFont(Font font)
134 {
135 return extractFontForInternalFont(register(font));
136 }
137
138 /** Gets a string for the font style in the form expected by java.awt.Font.decode(String). */
139 private String getStringForStyle(Font.Style style)
140 {
141 if (style == Font.Style.BOLD_ITALIC) return "BOLDITALIC";
142 else if (style == Font.Style.BOLD) return "BOLD";
143 else if (style == Font.Style.ITALIC) return "ITALIC";
144 else return "PLAIN";
145 }
146
147 /** Registers the given handle with the manager and returns the internal font. */
148 private java.awt.Font register(Font font)
149 {
150 if (register(null, font) == null) return null;
151
152 return _fontMap.get(font);
153 }
154
155 /** Registers the given font with the manager and returns the generated handle. */
156 private Font register(java.awt.Font swingFont)
157 {
158 return register(swingFont, null);
159 }
160
161 /** Registers a handle/font pair. */
162 private Font register(java.awt.Font swingFont, Font font)
163 {
164 if (swingFont == null && font == null) return null;
165
166 if (_fontMap.containsKey(font)) return font;
167
168 if (font == null) {
169 font = extractFontForInternalFont(swingFont);
170 } else if (swingFont == null) {
171 swingFont = java.awt.Font.decode(font.getFamilyName() + "-" + getStringForStyle(font.getStyle()) + "-" + font.getSize());
172 }
173
174 if (swingFont == null || font == null) return null;
175
176 _fontMap.put(font, swingFont);
177 _fontNames.add(swingFont.getFamily());
178
179 return font;
180 }
181
182 /** Creates a handle to match the given Swing font. */
183 private Font extractFontForInternalFont(java.awt.Font swingFont)
184 {
185 if (swingFont == null) return null;
186
187 Font font = new Font(swingFont.getFamily());
188 font.setStyle(Font.Style.PLAIN);
189 if (swingFont.isBold()) font.toggleBold();
190 if (swingFont.isItalic()) font.toggleItalic();
191 font.setSize(swingFont.getSize());
192 Number spacing = (Number) swingFont.getAttributes().get(java.awt.font.TextAttribute.TRACKING);
193 if (spacing != null) font.setSpacing(spacing.floatValue());
194
195 return font;
196 }
197
198 /** Gets the internal Swing font object for use by other Swing managers. */
199 public java.awt.Font getInternalFont(Font font)
200 {
201 return register(font);
202 }
203
204 /** Registers any standard fonts available on the system with the manager. */
205 private void registerSwingStandardFonts()
206 {
207 String[] standardFontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
208
209 for (String name : standardFontNames) {
210 register(new Font(name));
211 }
212 }
213}
Note: See TracBrowser for help on using the repository browser.