1 7 package javax.swing.text.html; 8 9 import java.awt.Polygon ; 10 import java.awt.Rectangle ; 11 import java.util.StringTokenizer ; 12 import java.util.Vector ; 13 import javax.swing.text.AttributeSet ; 14 15 23 class Map { 24 25 private String name; 26 27 private Vector areaAttributes; 28 30 private Vector areas; 31 32 public Map() { 33 } 34 35 public Map(String name) { 36 this.name = name; 37 } 38 39 42 public String getName() { 43 return name; 44 } 45 46 49 public void addArea(AttributeSet as) { 50 if (as == null) { 51 return; 52 } 53 if (areaAttributes == null) { 54 areaAttributes = new Vector (2); 55 } 56 areaAttributes.addElement(as.copyAttributes()); 57 } 58 59 62 public void removeArea(AttributeSet as) { 63 if (as != null && areaAttributes != null) { 64 int numAreas = (areas != null) ? areas.size() : 0; 65 for (int counter = areaAttributes.size() - 1; counter >= 0; 66 counter--) { 67 if (((AttributeSet )areaAttributes.elementAt(counter)). 68 isEqual(as)){ 69 areaAttributes.removeElementAt(counter); 70 if (counter < numAreas) { 71 areas.removeElementAt(counter); 72 } 73 } 74 } 75 } 76 } 77 78 81 public AttributeSet [] getAreas() { 82 int numAttributes = (areaAttributes != null) ? areaAttributes.size() : 83 0; 84 if (numAttributes != 0) { 85 AttributeSet [] retValue = new AttributeSet [numAttributes]; 86 87 areaAttributes.copyInto(retValue); 88 return retValue; 89 } 90 return null; 91 } 92 93 99 public AttributeSet getArea(int x, int y, int width, int height) { 100 int numAttributes = (areaAttributes != null) ? 101 areaAttributes.size() : 0; 102 103 if (numAttributes > 0) { 104 int numAreas = (areas != null) ? areas.size() : 0; 105 106 if (areas == null) { 107 areas = new Vector (numAttributes); 108 } 109 for (int counter = 0; counter < numAttributes; counter++) { 110 if (counter >= numAreas) { 111 areas.addElement(createRegionContainment 112 ((AttributeSet )areaAttributes.elementAt(counter))); 113 } 114 RegionContainment rc = (RegionContainment)areas. 115 elementAt(counter); 116 if (rc != null && rc.contains(x, y, width, height)) { 117 return (AttributeSet )areaAttributes.elementAt(counter); 118 } 119 } 120 } 121 return null; 122 } 123 124 128 protected RegionContainment createRegionContainment 129 (AttributeSet attributes) { 130 Object shape = attributes.getAttribute(HTML.Attribute.SHAPE); 131 132 if (shape == null) { 133 shape = "rect"; 134 } 135 if (shape instanceof String ) { 136 String shapeString = ((String )shape).toLowerCase(); 137 RegionContainment rc = null; 138 139 try { 140 if (shapeString.equals("rect")) { 141 rc = new RectangleRegionContainment(attributes); 142 } 143 else if (shapeString.equals("circle")) { 144 rc = new CircleRegionContainment(attributes); 145 } 146 else if (shapeString.equals("poly")) { 147 rc = new PolygonRegionContainment(attributes); 148 } 149 else if (shapeString.equals("default")) { 150 rc = DefaultRegionContainment.sharedInstance(); 151 } 152 } catch (RuntimeException re) { 153 rc = null; 155 } 156 return rc; 157 } 158 return null; 159 } 160 161 167 static protected int[] extractCoords(Object stringCoords) { 168 if (stringCoords == null || !(stringCoords instanceof String )) { 169 return null; 170 } 171 172 StringTokenizer st = new StringTokenizer ((String )stringCoords, 173 ", \t\n\r"); 174 int[] retValue = null; 175 int numCoords = 0; 176 177 while(st.hasMoreElements()) { 178 String token = st.nextToken(); 179 int scale; 180 181 if (token.endsWith("%")) { 182 scale = -1; 183 token = token.substring(0, token.length() - 1); 184 } 185 else { 186 scale = 1; 187 } 188 try { 189 int intValue = Integer.parseInt(token); 190 191 if (retValue == null) { 192 retValue = new int[4]; 193 } 194 else if(numCoords == retValue.length) { 195 int[] temp = new int[retValue.length * 2]; 196 197 System.arraycopy(retValue, 0, temp, 0, retValue.length); 198 retValue = temp; 199 } 200 retValue[numCoords++] = intValue * scale; 201 } catch (NumberFormatException nfe) { 202 return null; 203 } 204 } 205 if (numCoords > 0 && numCoords != retValue.length) { 206 int[] temp = new int[numCoords]; 207 208 System.arraycopy(retValue, 0, temp, 0, numCoords); 209 retValue = temp; 210 } 211 return retValue; 212 } 213 214 215 219 interface RegionContainment { 220 226 public boolean contains(int x, int y, int width, int height); 227 } 228 229 230 233 static class RectangleRegionContainment implements RegionContainment { 234 237 float[] percents; 238 239 int lastWidth; 240 241 int lastHeight; 242 243 int x0; 244 int y0; 245 246 int x1; 247 int y1; 248 249 public RectangleRegionContainment(AttributeSet as) { 250 int[] coords = Map.extractCoords(as.getAttribute(HTML. 251 Attribute.COORDS)); 252 253 percents = null; 254 if (coords == null || coords.length != 4) { 255 throw new RuntimeException ("Unable to parse rectangular area"); 256 } 257 else { 258 x0 = coords[0]; 259 y0 = coords[1]; 260 x1 = coords[2]; 261 y1 = coords[3]; 262 if (x0 < 0 || y0 < 0 || x1 < 0 || y1 < 0) { 263 percents = new float[4]; 264 lastWidth = lastHeight = -1; 265 for (int counter = 0; counter < 4; counter++) { 266 if (coords[counter] < 0) { 267 percents[counter] = Math.abs 268 (coords[counter]) / 100.0f; 269 } 270 else { 271 percents[counter] = -1.0f; 272 } 273 } 274 } 275 } 276 } 277 278 public boolean contains(int x, int y, int width, int height) { 279 if (percents == null) { 280 return contains(x, y); 281 } 282 if (lastWidth != width || lastHeight != height) { 283 lastWidth = width; 284 lastHeight = height; 285 if (percents[0] != -1.0f) { 286 x0 = (int)(percents[0] * width); 287 } 288 if (percents[1] != -1.0f) { 289 y0 = (int)(percents[1] * height); 290 } 291 if (percents[2] != -1.0f) { 292 x1 = (int)(percents[2] * width); 293 } 294 if (percents[3] != -1.0f) { 295 y1 = (int)(percents[3] * height); 296 } 297 } 298 return contains(x, y); 299 } 300 301 public boolean contains(int x, int y) { 302 return ((x >= x0 && x <= x1) && 303 (y >= y0 && y <= y1)); 304 } 305 } 306 307 308 311 static class PolygonRegionContainment extends Polygon implements 312 RegionContainment { 313 315 float[] percentValues; 316 int[] percentIndexs; 317 318 int lastWidth; 319 320 int lastHeight; 321 322 public PolygonRegionContainment(AttributeSet as) { 323 int[] coords = Map.extractCoords(as.getAttribute(HTML.Attribute. 324 COORDS)); 325 326 if (coords == null || coords.length == 0 || 327 coords.length % 2 != 0) { 328 throw new RuntimeException ("Unable to parse polygon area"); 329 } 330 else { 331 int numPercents = 0; 332 333 lastWidth = lastHeight = -1; 334 for (int counter = coords.length - 1; counter >= 0; 335 counter--) { 336 if (coords[counter] < 0) { 337 numPercents++; 338 } 339 } 340 341 if (numPercents > 0) { 342 percentIndexs = new int[numPercents]; 343 percentValues = new float[numPercents]; 344 for (int counter = coords.length - 1, pCounter = 0; 345 counter >= 0; counter--) { 346 if (coords[counter] < 0) { 347 percentValues[pCounter] = coords[counter] / 348 -100.0f; 349 percentIndexs[pCounter] = counter; 350 pCounter++; 351 } 352 } 353 } 354 else { 355 percentIndexs = null; 356 percentValues = null; 357 } 358 npoints = coords.length / 2; 359 xpoints = new int[npoints]; 360 ypoints = new int[npoints]; 361 362 for (int counter = 0; counter < npoints; counter++) { 363 xpoints[counter] = coords[counter + counter]; 364 ypoints[counter] = coords[counter + counter + 1]; 365 } 366 } 367 } 368 369 public boolean contains(int x, int y, int width, int height) { 370 if (percentValues == null || (lastWidth == width && 371 lastHeight == height)) { 372 return contains(x, y); 373 } 374 bounds = null; 376 lastWidth = width; 377 lastHeight = height; 378 float fWidth = (float)width; 379 float fHeight = (float)height; 380 for (int counter = percentValues.length - 1; counter >= 0; 381 counter--) { 382 if (percentIndexs[counter] % 2 == 0) { 383 xpoints[percentIndexs[counter] / 2] = 385 (int)(percentValues[counter] * fWidth); 386 } 387 else { 388 ypoints[percentIndexs[counter] / 2] = 390 (int)(percentValues[counter] * fHeight); 391 } 392 } 393 return contains(x, y); 394 } 395 } 396 397 398 401 static class CircleRegionContainment implements RegionContainment { 402 403 int x; 404 405 int y; 406 407 int radiusSquared; 408 409 float[] percentValues; 410 411 int lastWidth; 412 413 int lastHeight; 414 415 public CircleRegionContainment(AttributeSet as) { 416 int[] coords = Map.extractCoords(as.getAttribute(HTML.Attribute. 417 COORDS)); 418 419 if (coords == null || coords.length != 3) { 420 throw new RuntimeException ("Unable to parse circular area"); 421 } 422 x = coords[0]; 423 y = coords[1]; 424 radiusSquared = coords[2] * coords[2]; 425 if (coords[0] < 0 || coords[1] < 0 || coords[2] < 0) { 426 lastWidth = lastHeight = -1; 427 percentValues = new float[3]; 428 for (int counter = 0; counter < 3; counter++) { 429 if (coords[counter] < 0) { 430 percentValues[counter] = coords[counter] / 431 -100.0f; 432 } 433 else { 434 percentValues[counter] = -1.0f; 435 } 436 } 437 } 438 else { 439 percentValues = null; 440 } 441 } 442 443 public boolean contains(int x, int y, int width, int height) { 444 if (percentValues != null && (lastWidth != width || 445 lastHeight != height)) { 446 int newRad = Math.min(width, height) / 2; 447 448 lastWidth = width; 449 lastHeight = height; 450 if (percentValues[0] != -1.0f) { 451 this.x = (int)(percentValues[0] * width); 452 } 453 if (percentValues[1] != -1.0f) { 454 this.y = (int)(percentValues[1] * height); 455 } 456 if (percentValues[2] != -1.0f) { 457 radiusSquared = (int)(percentValues[2] * 458 Math.min(width, height)); 459 radiusSquared *= radiusSquared; 460 } 461 } 462 return (((x - this.x) * (x - this.x) + 463 (y - this.y) * (y - this.y)) <= radiusSquared); 464 } 465 } 466 467 468 473 static class DefaultRegionContainment implements RegionContainment { 474 475 static DefaultRegionContainment si = null; 476 477 public static DefaultRegionContainment sharedInstance() { 478 if (si == null) { 479 si = new DefaultRegionContainment(); 480 } 481 return si; 482 } 483 484 public boolean contains(int x, int y, int width, int height) { 485 return (x <= width && x >= 0 && y >= 0 && y <= width); 486 } 487 } 488 } 489 | Popular Tags |