1 19 20 package org.netbeans.editor; 21 22 import java.awt.Component ; 23 import java.awt.Font ; 24 import java.awt.FontMetrics ; 25 import java.awt.Graphics ; 26 import java.awt.Graphics2D ; 27 import java.awt.font.LineMetrics ; 28 import java.util.HashMap ; 29 30 37 38 public class FontMetricsCache { 39 40 private static HashMap font2FM = new HashMap (); 41 42 private static HashMap font2Info = new HashMap (); 43 44 49 public static synchronized FontMetrics getFontMetrics(Font f, Component c) { 50 Object fm = font2FM.get(f); 51 if (fm == null) { 52 fm = c.getFontMetrics(f); 53 font2FM.put(f, fm); 54 } 55 return (FontMetrics )fm; 56 } 57 58 63 public static synchronized FontMetrics getFontMetrics(Font f, Graphics g) { 64 Object fm = font2FM.get(f); 65 if (fm == null) { 66 fm = g.getFontMetrics(f); 67 font2FM.put(f, fm); 68 } 69 return (FontMetrics )fm; 70 } 71 72 76 public static synchronized Info getInfo(Font 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 89 public static synchronized void clear() { 90 font2FM.clear(); 91 font2Info.clear(); 92 } 93 94 public interface Info { 95 96 97 public int getSpaceWidth(Graphics g); 98 99 100 public int getSpaceWidth(Component c); 101 102 105 public float getStrikethroughOffset(Graphics g); 106 107 110 public float getStrikethroughOffset(Component c); 111 112 113 public float getStrikethroughThickness(Graphics g); 114 115 116 public float getStrikethroughThickness(Component c); 117 118 119 public float getUnderlineOffset(Graphics g); 120 121 122 public float getUnderlineOffset(Component c); 123 124 125 public float getUnderlineThickness(Graphics g); 126 127 128 public float getUnderlineThickness(Component 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 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 font) { 153 this.font = font; 154 } 155 156 private synchronized void initSpaceWidth(Graphics g, Component c) { 157 FontMetrics fm = (g != null) ? getFontMetrics(font, g) : getFontMetrics(font, c); 158 spaceWidth = fm.stringWidth(" "); if (spaceWidth <= 0) { 160 spaceWidth = fm.stringWidth("A") / 3; } 162 inited |= SW_INITED; 163 } 164 165 private synchronized void initStrikethrough(Graphics g) { 166 LineMetrics lm = font.getLineMetrics("aAyY", ((Graphics2D )g).getFontRenderContext()); strikethroughOffset = lm.getStrikethroughOffset(); 168 strikethroughThickness = lm.getStrikethroughThickness(); 169 inited |= ST_INITED; 170 } 171 172 private synchronized void initUnderline(Graphics g) { 173 LineMetrics lm = font.getLineMetrics("aAyY", ((Graphics2D )g).getFontRenderContext()); underlineOffset = lm.getUnderlineOffset(); 175 underlineThickness = lm.getUnderlineThickness(); 176 inited |= UL_INITED; 177 } 178 179 180 public int getSpaceWidth(Graphics g) { 181 if ((inited & SW_INITED) == 0) { 182 initSpaceWidth(g, null); 183 } 184 185 return spaceWidth; 186 } 187 188 189 public int getSpaceWidth(Component c) { 190 if ((inited & SW_INITED) == 0) { 191 initSpaceWidth(null, c); 192 } 193 194 return spaceWidth; 195 } 196 197 200 public float getStrikethroughOffset(Graphics g) { 201 if ((inited & ST_INITED) == 0) { 202 initStrikethrough(g); 203 } 204 205 return strikethroughOffset; 206 } 207 208 211 public float getStrikethroughOffset(Component c) { 212 if ((inited & ST_INITED) == 0) { 213 initStrikethrough(c.getGraphics()); 214 } 215 216 return strikethroughOffset; 217 } 218 219 220 public float getStrikethroughThickness(Graphics g) { 221 if ((inited & ST_INITED) == 0) { 222 initStrikethrough(g); 223 } 224 225 return strikethroughThickness; 226 } 227 228 229 public float getStrikethroughThickness(Component c) { 230 if ((inited & ST_INITED) == 0) { 231 initStrikethrough(c.getGraphics()); 232 } 233 234 return strikethroughThickness; 235 } 236 237 238 public float getUnderlineOffset(Graphics g) { 239 if ((inited & UL_INITED) == 0) { 240 initUnderline(g); 241 } 242 243 return underlineOffset; 244 } 245 246 247 public float getUnderlineOffset(Component c) { 248 if ((inited & UL_INITED) == 0) { 249 initUnderline(c.getGraphics()); 250 } 251 252 return underlineOffset; 253 } 254 255 256 public float getUnderlineThickness(Graphics g) { 257 if ((inited & UL_INITED) == 0) { 258 initUnderline(g); 259 } 260 261 return underlineThickness; 262 } 263 264 265 public float getUnderlineThickness(Component 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 |