1 22 23 27 28 package org.netbeans.lib.terminalemulator; 29 30 import java.awt.*; 31 import java.util.AbstractMap ; 32 import java.util.HashMap ; 33 34 class MyFontMetrics { 35 36 48 49 static class WidthCache { 50 byte [] cache = new byte[Character.MAX_VALUE+1]; 51 int reference_count = 1; 52 53 public void up() { 54 reference_count ++; 55 if (reference_count == 1) 56 cache = new byte[Character.MAX_VALUE+1]; 57 } 58 59 public void down() { 60 if (reference_count == 0) 61 return; 62 reference_count --; 63 if (reference_count == 0) 64 cache = null; 65 } 66 67 public boolean isMultiCell() { 68 return multiCell; 69 } 70 public void setMultiCell(boolean multiCell) { 71 this.multiCell = multiCell; 72 } 73 private boolean multiCell = false; 74 } 75 76 99 100 private static class CacheFactory { 101 static synchronized WidthCache cacheForFontMetrics(FontMetrics fm) { 102 WidthCache entry = (WidthCache) map.get(fm); 103 if (entry == null) { 104 entry = new WidthCache(); 105 map.put(fm, entry); 106 } else { 107 entry.up(); 108 } 109 return entry; 110 } 111 112 static synchronized void disposeBy(FontMetrics fm) { 113 WidthCache entry = (WidthCache) map.get(fm); 114 if (entry != null) 115 entry.down(); 116 } 117 118 private static AbstractMap map = new HashMap (); 119 } 120 121 122 public MyFontMetrics(Component component, Font font) { 123 fm = component.getFontMetrics(font); 124 width = fm.charWidth('a'); 125 height = fm.getHeight(); 126 ascent = fm.getAscent(); 127 leading = fm.getLeading(); 128 129 140 height -= leading; 141 leading = 0; 142 143 cwidth_cache = CacheFactory.cacheForFontMetrics(fm); 144 } 145 146 protected void finalize() { 147 CacheFactory.disposeBy(fm); 148 } 149 150 151 public int width; 152 public int height; 153 public int ascent; 154 public int leading; 155 public FontMetrics fm; 156 157 private WidthCache cwidth_cache; 158 159 public boolean isMultiCell() { 160 return cwidth_cache.isMultiCell(); 161 } 162 163 167 168 public int wcwidth(char c) { 169 int cell_width = cwidth_cache.cache[c]; 171 if (cell_width == 0) { 172 int pixel_width = fm.charWidth(c); 174 175 if (pixel_width == width) { 176 cell_width = 1; 177 178 } else if (pixel_width == 0) { 179 cell_width = 1; 180 181 } else { 182 int mod = pixel_width % width; 185 int rounded_width = pixel_width; 186 if (mod != 0) 187 rounded_width = pixel_width + (width - mod); 188 cell_width = rounded_width/width; 189 if (cell_width == 0) 190 cell_width = 1; 191 192 cwidth_cache.setMultiCell(true); 193 } 194 195 cwidth_cache.cache[c] = (byte) cell_width; 196 } 197 return cell_width; 198 } 199 200 204 void checkForMultiCell(char c) { 205 wcwidth(c); 206 } 207 } 208 | Popular Tags |