1 19 package org.openide.text; 20 21 import java.awt.Color ; 22 import java.awt.Font ; 23 import java.awt.font.TextAttribute ; 24 25 import java.text.AttributedCharacterIterator ; 26 27 import java.util.Collections ; 28 import java.util.HashMap ; 29 import java.util.HashSet ; 30 import java.util.Map ; 31 import java.util.Set ; 32 33 34 39 public class AttributedCharacters extends Object { 40 41 protected char[] chars; 42 43 44 protected Font [] fonts; 45 46 47 protected Color [] colors; 48 49 50 protected int[] runStart; 51 52 53 protected int[] runLimit; 54 55 56 protected int current; 57 58 public AttributedCharacters() { 59 chars = new char[10]; 60 fonts = new Font [10]; 61 colors = new Color [10]; 62 runStart = new int[10]; 63 runLimit = new int[10]; 64 current = -1; 65 } 66 67 72 public void append(char c, Font f, Color color) { 73 if (f == null) { 74 return; 75 } 76 77 if (++current == chars.length) { 78 char[] ctmp = new char[2 * chars.length]; 79 Font [] ftmp = new Font [2 * chars.length]; 80 Color [] cotmp = new Color [2 * chars.length]; 81 int[] rstmp = new int[2 * chars.length]; 82 int[] rltmp = new int[2 * chars.length]; 83 System.arraycopy(chars, 0, ctmp, 0, chars.length); 84 System.arraycopy(fonts, 0, ftmp, 0, chars.length); 85 System.arraycopy(colors, 0, cotmp, 0, chars.length); 86 System.arraycopy(runStart, 0, rstmp, 0, chars.length); 87 System.arraycopy(runLimit, 0, rltmp, 0, chars.length); 88 chars = ctmp; 89 fonts = ftmp; 90 colors = cotmp; 91 runStart = rstmp; 92 runLimit = rltmp; 93 } 94 95 chars[current] = c; 96 fonts[current] = f; 97 colors[current] = color; 98 99 if (current != 0) { 100 int prev = current - 1; 101 102 if (fonts[prev].equals(f) && colors[prev].equals(color)) { 103 runLimit[runStart[current] = runStart[prev]] = current; 104 } else { 105 runLimit[current] = current; 106 runStart[current] = current; 107 } 108 } 109 } 110 111 116 public void append(char[] a, Font f, Color color) { 117 if ((a == null) || (a.length == 0) || (f == null) || (color == null)) { 118 return; 119 } 120 121 if ((++current + a.length) >= chars.length) { 123 int size = Math.max(current + a.length, 2 * chars.length); 124 char[] ctmp = new char[size]; 125 Font [] ftmp = new Font [size]; 126 Color [] cotmp = new Color [size]; 127 int[] rstmp = new int[size]; 128 int[] rltmp = new int[size]; 129 System.arraycopy(chars, 0, ctmp, 0, chars.length); 130 System.arraycopy(fonts, 0, ftmp, 0, fonts.length); 131 System.arraycopy(colors, 0, cotmp, 0, chars.length); 132 System.arraycopy(runStart, 0, rstmp, 0, chars.length); 133 System.arraycopy(runLimit, 0, rltmp, 0, chars.length); 134 chars = ctmp; 135 fonts = ftmp; 136 colors = cotmp; 137 runStart = rstmp; 138 runLimit = rltmp; 139 } 140 141 System.arraycopy(a, 0, chars, current, a.length); 143 144 for (int i = 0; i < a.length; i++) { 145 fonts[i + current] = f; 146 colors[i + current] = color; 147 } 148 149 int prev = current - 1; 151 int pseudo = (current + a.length) - 1; 152 153 if (prev < 0) { runLimit[0] = pseudo; 155 } else { 156 int replace; 157 158 if (fonts[prev].equals(f) && colors[prev].equals(color)) { runLimit[runStart[prev]] = pseudo; 160 replace = runStart[prev]; 161 } else { runLimit[current] = pseudo; 163 replace = current; 164 } 165 166 for (int i = current; i <= pseudo; i++) { 168 runStart[i] = replace; 169 } 170 } 171 172 current = pseudo; 173 } 174 175 178 public AttributedCharacterIterator iterator() { 179 int size = current + 1; 180 char[] cs = new char[size]; 181 Font [] fs = new Font [size]; 182 Color [] colos = new Color [size]; 183 int[] rstmp = new int[size]; 184 int[] rltmp = new int[size]; 185 System.arraycopy(runStart, 0, rstmp, 0, size); 186 System.arraycopy(runLimit, 0, rltmp, 0, size); 187 System.arraycopy(chars, 0, cs, 0, size); 188 System.arraycopy(fonts, 0, fs, 0, size); 189 System.arraycopy(colors, 0, colos, 0, size); 190 191 AttributedCharacterIterator ret = new AttributedCharacterIteratorImpl(cs, fs, colos, rstmp, rltmp); 192 193 return ret; 194 } 195 196 197 public static class AttributedCharacterIteratorImpl implements AttributedCharacterIterator { 198 199 protected int current; 200 201 202 protected char[] chars; 203 204 205 protected Font [] fonts; 206 207 208 protected Color [] colors; 209 210 211 protected int[] runStart; 212 213 214 protected int[] runLimit; 215 216 217 protected Set <AttributedCharacterIterator.Attribute > singleton; 218 219 public AttributedCharacterIteratorImpl(char[] chars, Font [] fonts, Color [] colors, int[] rs, int[] rl) { 220 this.chars = chars; 221 this.fonts = fonts; 222 this.colors = colors; 223 runStart = rs; 224 runLimit = rl; 225 } 226 227 229 233 public Object clone() { 234 try { 235 return super.clone(); 236 } catch (CloneNotSupportedException e) { 237 return null; 239 } 240 } 241 242 245 public char current() { 246 if (current >= chars.length) { 247 return DONE; 248 } 249 250 return chars[current]; 251 } 252 253 256 public char first() { 257 current = 0; 258 259 if (current >= chars.length) { 260 return DONE; 261 } 262 263 return chars[current]; 264 } 265 266 269 public int getBeginIndex() { 270 return 0; 271 } 272 273 276 public int getEndIndex() { 277 return chars.length; 278 } 279 280 283 public int getIndex() { 284 return current; 285 } 286 287 290 public char last() { 291 int end = getEndIndex(); 292 293 if (end == 0) { 294 return DONE; 295 } 296 297 return chars[current = end - 1]; 298 } 299 300 303 public char next() { 304 if (current >= (getEndIndex() - 1)) { 305 return DONE; 306 } 307 308 return chars[++current]; 309 } 310 311 314 public char previous() { 315 if (current == 0) { 316 return DONE; 317 } 318 319 return chars[--current]; 320 } 321 322 326 public char setIndex(int i) { 327 if (i < 0) { 328 throw new IllegalArgumentException (); 329 } 330 331 if (i == getEndIndex()) { 332 current = getEndIndex(); 333 334 return DONE; 335 } 336 337 return chars[current = i]; 338 } 339 340 342 345 public Set <AttributedCharacterIterator.Attribute > getAllAttributeKeys() { 346 if (singleton == null) { 347 Set <AttributedCharacterIterator.Attribute > l = new HashSet <AttributedCharacterIterator.Attribute >(4); 348 l.add(TextAttribute.FONT); 349 l.add(TextAttribute.FOREGROUND); 350 singleton = Collections.unmodifiableSet(l); 351 } 352 353 return singleton; 354 } 355 356 360 public Object getAttribute(AttributedCharacterIterator.Attribute att) { 361 if (att == TextAttribute.FONT) { 362 return fonts[getIndex()]; 363 } else if (att == TextAttribute.FOREGROUND) { 364 return colors[getIndex()]; 365 } else { 366 return null; 367 } 368 } 369 370 373 public Map <AttributedCharacterIterator.Attribute ,Object > getAttributes() { 374 Map <AttributedCharacterIterator.Attribute ,Object > m = new HashMap <AttributedCharacterIterator.Attribute ,Object >(1); 375 m.put(TextAttribute.FONT, fonts[getIndex()]); 376 m.put(TextAttribute.FOREGROUND, colors[getIndex()]); 377 378 return m; 379 } 380 381 384 public int getRunLimit() { 385 return runLimit[runStart[getIndex()]] + 1; 386 } 387 388 391 public int getRunLimit(AttributedCharacterIterator.Attribute att) { 392 if ((att != TextAttribute.FONT) && (att != TextAttribute.FOREGROUND)) { 393 return getEndIndex(); } 395 396 return getRunLimit(); 397 } 398 399 402 public int getRunLimit(Set <? extends AttributedCharacterIterator.Attribute > attributes) { 403 if (attributes.contains(TextAttribute.FONT) || attributes.contains(TextAttribute.FOREGROUND)) { 404 return getRunLimit(); 405 } else { 406 return getEndIndex(); 407 } 408 } 409 410 413 public int getRunStart() { 414 return runStart[getIndex()]; 415 } 416 417 420 public int getRunStart(AttributedCharacterIterator.Attribute att) { 421 if ((att != TextAttribute.FONT) && (att != TextAttribute.FOREGROUND)) { 422 return 0; } 424 425 return getRunStart(); 426 } 427 428 431 public int getRunStart(Set <? extends AttributedCharacterIterator.Attribute > attributes) { 432 if ((attributes.contains(TextAttribute.FONT)) || attributes.contains(TextAttribute.FOREGROUND)) { 433 return getRunStart(); 434 } else { 435 return 0; 436 } 437 } 438 } 439 } 440 | Popular Tags |