1 19 20 package jxl.biff.drawing; 21 22 import java.io.IOException ; 23 import java.util.HashMap ; 24 import java.util.ArrayList ; 25 import java.util.Iterator ; 26 27 import common.Assert; 28 import common.Logger; 29 30 import jxl.read.biff.Record; 31 import jxl.write.biff.File; 32 33 37 public class DrawingGroup implements EscherStream 38 { 39 42 private static Logger logger = Logger.getLogger(DrawingGroup.class); 43 44 47 private byte[] drawingData; 48 49 52 private EscherContainer escherData; 53 54 57 private BStoreContainer bstoreContainer; 58 59 62 private boolean initialized; 63 64 67 private ArrayList drawings; 68 69 72 private int numBlips; 73 74 77 private int numCharts; 78 79 82 private int drawingGroupId; 83 84 88 private boolean drawingsOmitted; 89 90 93 private Origin origin; 94 95 99 private HashMap imageFiles; 100 101 104 private int maxObjectId; 105 106 109 private int maxShapeId; 110 111 116 public DrawingGroup(Origin o) 117 { 118 origin = o; 119 initialized = o == Origin.WRITE ? true : false; 120 drawings = new ArrayList (); 121 imageFiles = new HashMap (); 122 drawingsOmitted = false; 123 maxObjectId = 1; 124 maxShapeId = 1024; 125 } 126 127 135 public DrawingGroup(DrawingGroup dg) 136 { 137 drawingData = dg.drawingData; 138 escherData = dg.escherData; 139 bstoreContainer = dg.bstoreContainer; 140 initialized = dg.initialized; 141 drawingData = dg.drawingData; 142 escherData = dg.escherData; 143 bstoreContainer = dg.bstoreContainer; 144 numBlips = dg.numBlips; 145 numCharts = dg.numCharts; 146 drawingGroupId = dg.drawingGroupId; 147 drawingsOmitted = dg.drawingsOmitted; 148 origin = dg.origin; 149 imageFiles = (HashMap ) dg.imageFiles.clone(); 150 maxObjectId = dg.maxObjectId; 151 maxShapeId = dg.maxShapeId; 152 153 drawings = new ArrayList (); 156 } 157 158 167 public void add(MsoDrawingGroupRecord mso) 168 { 169 addData(mso.getData()); 170 } 171 172 178 public void add(Record cont) 179 { 180 addData(cont.getData()); 181 } 182 183 186 private void addData(byte[] msodata) 187 { 188 if (drawingData == null) 189 { 190 drawingData = new byte[msodata.length]; 191 System.arraycopy(msodata, 0, drawingData, 0, msodata.length); 192 return; 193 } 194 195 byte[] newdata = new byte[drawingData.length + msodata.length]; 197 System.arraycopy(drawingData, 0, newdata, 0, drawingData.length); 198 System.arraycopy(msodata, 0, newdata, drawingData.length, msodata.length); 199 drawingData = newdata; 200 } 201 202 207 final void addDrawing(DrawingGroupObject d) 208 { 209 drawings.add(d); 210 maxObjectId = Math.max(maxObjectId, d.getObjectId()); 211 maxShapeId = Math.max(maxShapeId, d.getShapeId()); 212 } 213 214 219 public void add(Chart c) 220 { 221 numCharts++; 222 } 223 224 229 public void add(DrawingGroupObject d) 230 { 231 if (origin == Origin.READ) 232 { 233 origin = Origin.READ_WRITE; 234 BStoreContainer bsc = getBStoreContainer(); Dgg dgg = (Dgg) escherData.getChildren()[0]; 236 drawingGroupId = dgg.getCluster(1).drawingGroupId - numBlips - 1; 237 numBlips = dgg.getDrawingsSaved(); 238 239 if (bsc != null) 240 { 241 Assert.verify(numBlips == bsc.getNumBlips()); 242 } 243 } 244 245 if (!(d instanceof Drawing)) 246 { 247 maxObjectId++; 250 maxShapeId++; 251 d.setDrawingGroup(this); 252 d.setObjectId(maxObjectId, numBlips+1, maxShapeId); 253 if (drawings.size() > maxObjectId) 254 { 255 logger.warn("drawings length " + drawings.size() + 256 " exceeds the max object id " + maxObjectId); 257 } 258 return; 260 } 261 262 Drawing drawing = (Drawing) d; 263 264 Drawing refImage = 266 (Drawing) imageFiles.get(d.getImageFilePath()); 267 268 if (refImage == null) 269 { 270 maxObjectId++; 273 maxShapeId++; 274 drawings.add(drawing); 275 drawing.setDrawingGroup(this); 276 drawing.setObjectId(maxObjectId, numBlips+1, maxShapeId); 277 numBlips++; 278 imageFiles.put(drawing.getImageFilePath(), drawing); 279 } 280 else 281 { 282 refImage.setReferenceCount(refImage.getReferenceCount() + 1); 286 drawing.setDrawingGroup(this); 287 drawing.setObjectId(refImage.getObjectId(), 288 refImage.getBlipId(), 289 refImage.getShapeId()); 290 } 291 } 292 293 298 public void remove(DrawingGroupObject d) 299 { 300 if (origin == Origin.READ) 301 { 302 origin = Origin.READ_WRITE; 303 numBlips = getBStoreContainer().getNumBlips(); 304 Dgg dgg = (Dgg) escherData.getChildren()[0]; 305 drawingGroupId = dgg.getCluster(1).drawingGroupId - numBlips - 1 ; 306 } 307 308 EscherRecord[] children = getBStoreContainer().getChildren(); 310 BlipStoreEntry bse = (BlipStoreEntry) children[d.getBlipId()-1]; 311 312 bse.dereference(); 313 314 if (bse.getReferenceCount() == 0) 315 { 316 getBStoreContainer().remove(bse); 318 319 for (Iterator i = drawings.iterator() ; i.hasNext() ; ) 321 { 322 DrawingGroupObject drawing = (DrawingGroupObject) i.next(); 323 324 if (drawing.getBlipId() > d.getBlipId()) 325 { 326 drawing.setObjectId(drawing.getObjectId(), 327 drawing.getBlipId() - 1, 328 drawing.getShapeId()); 329 } 330 } 331 332 numBlips--; 333 } 334 } 335 336 337 340 private void initialize() 341 { 342 EscherRecordData er = new EscherRecordData(this, 0); 343 344 Assert.verify(er.isContainer()); 345 346 escherData = new EscherContainer(er); 347 348 Assert.verify(escherData.getLength() == drawingData.length); 349 Assert.verify(escherData.getType() == EscherRecordType.DGG_CONTAINER); 350 351 initialized = true; 352 } 353 354 359 private BStoreContainer getBStoreContainer() 360 { 361 if (bstoreContainer == null) 362 { 363 if (!initialized) 364 { 365 initialize(); 366 } 367 368 EscherRecord[] children = escherData.getChildren(); 369 if (children.length > 1 && 370 children[1].getType() == EscherRecordType.BSTORE_CONTAINER) 371 { 372 bstoreContainer = (BStoreContainer) children[1]; 373 } 374 else 375 { 376 } 378 } 379 380 return bstoreContainer; 381 } 382 383 388 public byte[] getData() 389 { 390 return drawingData; 391 } 392 393 399 public void write(File outputFile) throws IOException 400 { 401 if (origin == Origin.WRITE) 402 { 403 DggContainer dggContainer = new DggContainer(); 404 405 Dgg dgg = new Dgg(numBlips+numCharts+1, numBlips); 406 407 dgg.addCluster(1,0); 408 dgg.addCluster(numBlips+1,0); 409 410 dggContainer.add(dgg); 411 412 int drawingsAdded = 0; 413 BStoreContainer bstoreCont = new BStoreContainer(); 414 415 for (Iterator i = drawings.iterator(); i.hasNext();) 417 { 418 Object o = i.next(); 419 if (o instanceof Drawing) 420 { 421 Drawing d = (Drawing) o; 422 BlipStoreEntry bse = new BlipStoreEntry(d); 423 424 bstoreCont.add(bse); 425 drawingsAdded++; 426 } 427 } 428 if (drawingsAdded > 0) 429 { 430 bstoreCont.setNumBlips(drawingsAdded); 431 dggContainer.add(bstoreCont); 432 } 433 434 Opt opt = new Opt(); 435 436 dggContainer.add(opt); 437 438 SplitMenuColors splitMenuColors = new SplitMenuColors(); 439 dggContainer.add(splitMenuColors); 440 441 drawingData = dggContainer.getData(); 442 } 443 else if (origin == Origin.READ_WRITE) 444 { 445 DggContainer dggContainer = new DggContainer(); 446 447 Dgg dgg = new Dgg(numBlips+numCharts+1, numBlips); 448 449 dgg.addCluster(1,0); 450 dgg.addCluster(drawingGroupId+numBlips+1,0); 451 452 dggContainer.add(dgg); 453 454 BStoreContainer bstoreCont = new BStoreContainer(); 455 bstoreCont.setNumBlips(numBlips); 456 457 BStoreContainer readBStoreContainer = getBStoreContainer(); 459 460 if (readBStoreContainer != null) 461 { 462 EscherRecord[] children = readBStoreContainer.getChildren(); 463 for (int i = 0; i < children.length ; i++) 464 { 465 BlipStoreEntry bse = (BlipStoreEntry) children[i]; 466 bstoreCont.add(bse); 467 } 468 469 for (Iterator i = drawings.iterator(); i.hasNext();) 471 { 472 DrawingGroupObject dgo = (DrawingGroupObject) i.next(); 473 if (dgo instanceof Drawing) 474 { 475 Drawing d = (Drawing) dgo; 476 if (d.getOrigin() != Origin.READ) 477 { 478 BlipStoreEntry bse = new BlipStoreEntry(d); 479 bstoreCont.add(bse); 480 } 481 } 482 } 483 dggContainer.add(bstoreCont); 484 } 485 486 Opt opt = new Opt(); 487 488 opt.addProperty(191, false, false, 524296); 489 opt.addProperty(385, false, false, 134217737); 490 opt.addProperty(448, false, false, 134217792); 491 492 dggContainer.add(opt); 493 494 SplitMenuColors splitMenuColors = new SplitMenuColors(); 495 dggContainer.add(splitMenuColors); 496 497 drawingData = dggContainer.getData(); 498 } 499 500 MsoDrawingGroupRecord msodg = new MsoDrawingGroupRecord(drawingData); 501 outputFile.write(msodg); 502 } 503 504 509 final int getNumberOfBlips() 510 { 511 return numBlips; 512 } 513 514 521 byte[] getImageData(int blipId) 522 { 523 numBlips = getBStoreContainer().getNumBlips(); 524 525 Assert.verify(blipId <= numBlips); 526 Assert.verify(origin == Origin.READ || origin == Origin.READ_WRITE); 527 528 EscherRecord[] children = getBStoreContainer().getChildren(); 530 BlipStoreEntry bse = (BlipStoreEntry) children[blipId-1]; 531 532 return bse.getImageData(); 533 } 534 535 539 public void setDrawingsOmitted(MsoDrawingRecord mso, ObjRecord obj) 540 { 541 drawingsOmitted = true; 542 543 if (obj != null) 544 { 545 maxObjectId = Math.max(maxObjectId, obj.getObjectId()); 546 } 547 } 548 549 554 public boolean hasDrawingsOmitted() 555 { 556 return drawingsOmitted; 557 } 558 559 569 public void updateData(DrawingGroup dg) 570 { 571 drawingsOmitted = dg.drawingsOmitted; 572 maxObjectId = dg.maxObjectId; 573 maxShapeId = dg.maxShapeId; 574 } 575 } 576 | Popular Tags |