1 18 package org.apache.batik.gvt.font; 19 20 import java.awt.Shape ; 21 import java.awt.geom.Rectangle2D ; 22 import java.lang.ref.ReferenceQueue ; 23 import java.lang.ref.SoftReference ; 24 25 33 public class AWTGlyphGeometryCache { 34 35 38 protected final static int INITIAL_CAPACITY = 71; 39 40 43 protected Entry[] table; 44 45 48 protected int count; 49 50 53 protected ReferenceQueue referenceQueue = new ReferenceQueue (); 54 55 58 public AWTGlyphGeometryCache() { 59 table = new Entry[INITIAL_CAPACITY]; 60 } 61 62 66 public AWTGlyphGeometryCache(int c) { 67 table = new Entry[c]; 68 } 69 70 73 public int size() { 74 return count; 75 } 76 77 81 public Value get(char c) { 82 int hash = hashCode(c) & 0x7FFFFFFF; 83 int index = hash % table.length; 84 85 for (Entry e = table[index]; e != null; e = e.next) { 86 if ((e.hash == hash) && e.match(c)) { 87 return (Value)e.get(); 88 } 89 } 90 return null; 91 } 92 93 97 public Value put(char c, Value value) { 98 removeClearedEntries(); 99 100 int hash = hashCode(c) & 0x7FFFFFFF; 101 int index = hash % table.length; 102 103 Entry e = table[index]; 104 if (e != null) { 105 if ((e.hash == hash) && e.match(c)) { 106 Object old = e.get(); 107 table[index] = new Entry(hash, c, value, e.next); 108 return (Value)old; 109 } 110 Entry o = e; 111 e = e.next; 112 while (e != null) { 113 if ((e.hash == hash) && e.match(c)) { 114 Object old = e.get(); 115 e = new Entry(hash, c, value, e.next); 116 o.next = e; 117 return (Value)old; 118 } 119 120 o = e; 121 e = e.next; 122 } 123 } 124 125 int len = table.length; 127 if (count++ >= (len * 3) >>> 2) { 128 rehash(); 129 index = hash % table.length; 130 } 131 132 table[index] = new Entry(hash, c, value, table[index]); 133 return null; 134 } 135 136 139 public void clear() { 140 table = new Entry[INITIAL_CAPACITY]; 141 count = 0; 142 referenceQueue = new ReferenceQueue (); 143 } 144 145 148 protected void rehash () { 149 Entry[] oldTable = table; 150 151 table = new Entry[oldTable.length * 2 + 1]; 152 153 for (int i = oldTable.length-1; i >= 0; i--) { 154 for (Entry old = oldTable[i]; old != null;) { 155 Entry e = old; 156 old = old.next; 157 158 int index = e.hash % table.length; 159 e.next = table[index]; 160 table[index] = e; 161 } 162 } 163 } 164 165 168 protected int hashCode(char c) { 169 return c; 170 } 171 172 175 protected void removeClearedEntries() { 176 Entry e; 177 while ((e = (Entry)referenceQueue.poll()) != null) { 178 int index = e.hash % table.length; 179 Entry t = table[index]; 180 if (t == e) { 181 table[index] = e.next; 182 } else { 183 loop: for (;t!=null;) { 184 Entry c = t.next; 185 if (c == e) { 186 t.next = e.next; 187 break loop; 188 } 189 t = c; 190 } 191 } 192 count--; 193 } 194 } 195 196 199 public static class Value { 200 201 protected Shape outline; 202 protected Rectangle2D gmB; 203 protected Rectangle2D outlineBounds; 204 205 208 public Value(Shape outline, Rectangle2D gmB) { 209 this.outline = outline; 210 this.outlineBounds = outline.getBounds2D(); 211 this.gmB = gmB; 212 } 213 214 217 public Shape getOutline() { 218 return outline; 219 } 220 221 224 public Rectangle2D getBounds2D() { 225 return gmB; 226 } 227 228 231 public Rectangle2D getOutlineBounds2D() { 232 return outlineBounds; 233 } 234 } 235 236 239 protected class Entry extends SoftReference { 240 241 244 public int hash; 245 246 249 public char c; 250 251 254 public Entry next; 255 256 259 public Entry(int hash, char c, Value value, Entry next) { 260 super(value, referenceQueue); 261 this.hash = hash; 262 this.c = c; 263 this.next = next; 264 } 265 266 269 public boolean match(char o2) { 270 return (c == o2); 271 } 272 } 273 } 274 | Popular Tags |