KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > editor > FontMetricsCache


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.editor;
21
22 import java.awt.Component JavaDoc;
23 import java.awt.Font JavaDoc;
24 import java.awt.FontMetrics JavaDoc;
25 import java.awt.Graphics JavaDoc;
26 import java.awt.Graphics2D JavaDoc;
27 import java.awt.font.LineMetrics JavaDoc;
28 import java.util.HashMap JavaDoc;
29
30 /** Static cache that holds the font metrics for the fonts.
31 * This can generally speed up drawing if the metrics are not cached
32 * directly by the system.
33 *
34 * @author Miloslav Metelka
35 * @version 1.00
36 */

37
38 public class FontMetricsCache {
39
40     private static HashMap JavaDoc font2FM = new HashMap JavaDoc();
41
42     private static HashMap JavaDoc font2Info = new HashMap JavaDoc();
43
44     /** Get the font-metrics for the given font.
45     * @param font font for which the metrics is being retrieved.
46     * @param c component that is used to retrieve the metrics in case it's
47     * not yet in the cache.
48     */

49     public static synchronized FontMetrics JavaDoc getFontMetrics(Font JavaDoc f, Component JavaDoc c) {
50         Object JavaDoc fm = font2FM.get(f);
51         if (fm == null) {
52             fm = c.getFontMetrics(f);
53             font2FM.put(f, fm);
54         }
55         return (FontMetrics JavaDoc)fm;
56     }
57
58     /** Get the font-metrics for the given font.
59     * @param font font for which the metrics is being retrieved.
60     * @param g graphics that is used to retrieve the metrics in case it's
61     * not yet in the cache.
62     */

63     public static synchronized FontMetrics JavaDoc getFontMetrics(Font JavaDoc f, Graphics JavaDoc g) {
64         Object JavaDoc fm = font2FM.get(f);
65         if (fm == null) {
66             fm = g.getFontMetrics(f);
67             font2FM.put(f, fm);
68         }
69         return (FontMetrics JavaDoc)fm;
70     }
71
72     /** Get the info about the space-width and strike-through and underline
73     * constants.
74     * @param font font for which the info is being retrieved.
75     */

76     public static synchronized Info getInfo(Font JavaDoc f) {
77         Info info = (Info)font2Info.get(f);
78         if (info == null) {
79             info = new InfoImpl(f);
80             font2Info.put(f, info);
81         }
82         return info;
83     }
84
85     /** Clear all the metrics from the cache. It's usually done
86     * when any of the editor ui is being garbage collected to
87     * ensure there will be no more unused metrics.
88     */

89     public static synchronized void clear() {
90         font2FM.clear();
91         font2Info.clear();
92     }
93
94     public interface Info {
95
96         /** Returns the width of the space character */
97         public int getSpaceWidth(Graphics JavaDoc g);
98
99         /** Returns the width of the space character */
100         public int getSpaceWidth(Component JavaDoc c);
101
102         /** Returns the position of the strike-through line
103         * relative to the baseline.
104         */

105         public float getStrikethroughOffset(Graphics JavaDoc g);
106
107         /** Returns the position of the strike-through line
108         * relative to the baseline.
109         */

110         public float getStrikethroughOffset(Component JavaDoc c);
111
112         /** Returns the thickness of the strike-through line. */
113         public float getStrikethroughThickness(Graphics JavaDoc g);
114
115         /** Returns the thickness of the strike-through line. */
116         public float getStrikethroughThickness(Component JavaDoc c);
117
118         /** Returns the position of the underline relative to the baseline. */
119         public float getUnderlineOffset(Graphics JavaDoc g);
120
121         /** Returns the position of the underline relative to the baseline. */
122         public float getUnderlineOffset(Component JavaDoc c);
123
124         /** Returns the thickness of the underline. */
125         public float getUnderlineThickness(Graphics JavaDoc g);
126
127         /** Returns the thickness of the underline. */
128         public float getUnderlineThickness(Component JavaDoc c);
129
130     }
131
132     private static class InfoImpl implements Info {
133
134         private static final int SW_INITED = 1;
135         private static final int ST_INITED = 2;
136         private static final int UL_INITED = 4;
137
138         private Font JavaDoc font;
139
140         private int inited;
141
142         private int spaceWidth;
143
144         private float strikethroughOffset;
145
146         private float strikethroughThickness;
147
148         private float underlineOffset;
149
150         private float underlineThickness;
151
152         InfoImpl(Font JavaDoc font) {
153             this.font = font;
154         }
155
156         private synchronized void initSpaceWidth(Graphics JavaDoc g, Component JavaDoc c) {
157             FontMetrics JavaDoc fm = (g != null) ? getFontMetrics(font, g) : getFontMetrics(font, c);
158             spaceWidth = fm.stringWidth(" "); // NOI18N
159
if (spaceWidth <= 0) {
160                 spaceWidth = fm.stringWidth("A") / 3; // NOI18N
161
}
162             inited |= SW_INITED;
163         }
164
165         private synchronized void initStrikethrough(Graphics JavaDoc g) {
166             LineMetrics JavaDoc lm = font.getLineMetrics("aAyY", ((Graphics2D JavaDoc)g).getFontRenderContext()); // NOI18N
167
strikethroughOffset = lm.getStrikethroughOffset();
168             strikethroughThickness = lm.getStrikethroughThickness();
169             inited |= ST_INITED;
170         }
171
172         private synchronized void initUnderline(Graphics JavaDoc g) {
173             LineMetrics JavaDoc lm = font.getLineMetrics("aAyY", ((Graphics2D JavaDoc)g).getFontRenderContext()); // NOI18N
174
underlineOffset = lm.getUnderlineOffset();
175             underlineThickness = lm.getUnderlineThickness();
176             inited |= UL_INITED;
177         }
178
179         /** Returns the width of the space character */
180         public int getSpaceWidth(Graphics JavaDoc g) {
181             if ((inited & SW_INITED) == 0) {
182                 initSpaceWidth(g, null);
183             }
184
185             return spaceWidth;
186         }
187
188         /** Returns the width of the space character */
189         public int getSpaceWidth(Component JavaDoc c) {
190             if ((inited & SW_INITED) == 0) {
191                 initSpaceWidth(null, c);
192             }
193
194             return spaceWidth;
195         }
196
197         /** Returns the position of the strike-through line
198         * relative to the baseline.
199         */

200         public float getStrikethroughOffset(Graphics JavaDoc g) {
201             if ((inited & ST_INITED) == 0) {
202                 initStrikethrough(g);
203             }
204
205             return strikethroughOffset;
206         }
207
208         /** Returns the position of the strike-through line
209         * relative to the baseline.
210         */

211         public float getStrikethroughOffset(Component JavaDoc c) {
212             if ((inited & ST_INITED) == 0) {
213                 initStrikethrough(c.getGraphics());
214             }
215
216             return strikethroughOffset;
217         }
218
219         /** Returns the thickness of the strike-through line. */
220         public float getStrikethroughThickness(Graphics JavaDoc g) {
221             if ((inited & ST_INITED) == 0) {
222                 initStrikethrough(g);
223             }
224
225             return strikethroughThickness;
226         }
227
228         /** Returns the thickness of the strike-through line. */
229         public float getStrikethroughThickness(Component JavaDoc c) {
230             if ((inited & ST_INITED) == 0) {
231                 initStrikethrough(c.getGraphics());
232             }
233
234             return strikethroughThickness;
235         }
236
237         /** Returns the position of the underline relative to the baseline. */
238         public float getUnderlineOffset(Graphics JavaDoc g) {
239             if ((inited & UL_INITED) == 0) {
240                 initUnderline(g);
241             }
242
243             return underlineOffset;
244         }
245
246         /** Returns the position of the underline relative to the baseline. */
247         public float getUnderlineOffset(Component JavaDoc c) {
248             if ((inited & UL_INITED) == 0) {
249                 initUnderline(c.getGraphics());
250             }
251
252             return underlineOffset;
253         }
254
255         /** Returns the thickness of the underline. */
256         public float getUnderlineThickness(Graphics JavaDoc g) {
257             if ((inited & UL_INITED) == 0) {
258                 initUnderline(g);
259             }
260
261             return underlineThickness;
262         }
263
264         /** Returns the thickness of the underline. */
265         public float getUnderlineThickness(Component JavaDoc c) {
266             if ((inited & UL_INITED) == 0) {
267                 initUnderline(c.getGraphics());
268             }
269
270             return underlineThickness;
271         }
272
273     }
274
275
276 }
277
Popular Tags