1 26 27 package it.stefanochizzolini.clown.documents; 28 29 import it.stefanochizzolini.clown.files.File; 30 import it.stefanochizzolini.clown.objects.IPdfNumber; 31 import it.stefanochizzolini.clown.objects.PdfArray; 32 import it.stefanochizzolini.clown.objects.PdfDictionary; 33 import it.stefanochizzolini.clown.objects.PdfDirectObject; 34 import it.stefanochizzolini.clown.objects.PdfInteger; 35 import it.stefanochizzolini.clown.objects.PdfName; 36 import it.stefanochizzolini.clown.objects.PdfObjectWrapper; 37 import it.stefanochizzolini.clown.objects.PdfReference; 38 import it.stefanochizzolini.clown.util.NotImplementedException; 39 40 import java.util.ArrayList ; 41 import java.util.Arrays ; 42 import java.util.Collection ; 43 import java.util.Iterator ; 44 import java.util.List ; 45 import java.util.ListIterator ; 46 import java.util.NoSuchElementException ; 47 import java.util.Stack ; 48 49 52 public class Pages 53 extends PdfObjectWrapper<PdfDictionary> 54 implements List <Page> 55 { 56 61 Pages( 65 Document context 66 ) 67 { 68 super( 69 context.getFile(), 70 new PdfDictionary( 71 new PdfName[] 72 { 73 PdfName.Type, 74 PdfName.Kids, 75 PdfName.Count 76 }, 77 new PdfDirectObject[] 78 { 79 PdfName.Pages, 80 new PdfArray(), 81 new PdfInteger(0) 82 } 83 ) 84 ); 85 } 86 87 Pages( 88 PdfDirectObject baseObject 89 ) 90 { 91 super( 92 baseObject, 93 null ); 95 } 96 98 public Object clone( 101 Document context 102 ) 103 {throw new NotImplementedException();} 104 105 public void add( 107 int index, 108 Page page 109 ) 110 {commonAddAll(index,Arrays.asList(page));} 111 112 public boolean addAll( 113 int index, 114 Collection <? extends Page> pages 115 ) 116 {return commonAddAll(index,pages);} 117 118 public Page get( 119 int index 120 ) 121 { 122 128 int pageOffset = 0; 129 PdfDictionary parent = getBaseDataObject(); 130 PdfArray kids = (PdfArray)File.resolve(parent.get(PdfName.Kids)); 131 for( 132 int i = 0; 133 i < kids.size(); 134 i++ 135 ) 136 { 137 PdfReference kidReference = (PdfReference)kids.get(i); 138 PdfDictionary kid = (PdfDictionary)File.resolve(kidReference); 139 if(kid.get(PdfName.Type).equals(PdfName.Page)) { 142 if(pageOffset == index) { 145 return new Page(kidReference); 147 } 148 else { 150 pageOffset++; 152 } 153 } 154 else { 156 if(((PdfInteger)kid.get(PdfName.Count)).getValue() + pageOffset > index) { 159 parent = kid; 161 kids = (PdfArray)File.resolve(parent.get(PdfName.Kids)); 162 i = -1; 163 } 164 else { 166 pageOffset += ((PdfInteger)kid.get(PdfName.Count)).getValue(); 168 } 169 } 170 } 171 172 return null; 173 } 174 175 public int indexOf( 176 Object page 177 ) 178 {return ((Page)page).getIndex();} 179 180 public int lastIndexOf( 181 Object page 182 ) 183 { 184 187 return indexOf(page); 188 } 189 190 public ListIterator <Page> listIterator( 191 ) 192 {throw new NotImplementedException();} 193 194 public ListIterator <Page> listIterator( 195 int index 196 ) 197 {throw new NotImplementedException();} 198 199 public Page remove( 200 int index 201 ) 202 { 203 Page page = get(index); 204 remove(page); 205 206 return page; 207 } 208 209 public Page set( 210 int index, 211 Page page 212 ) 213 { 214 Page old = remove(index); 215 add(index,page); 216 217 return old; 218 } 219 220 public List <Page> subList( 221 int fromIndex, 222 int toIndex 223 ) 224 { 225 228 ArrayList <Page> pages = new ArrayList <Page>(toIndex - fromIndex); 229 int i = fromIndex; 230 Page page = get(i); 231 while(i++ < toIndex) 232 { 233 pages.add(page); 234 page = page.getNext(); 235 } 236 237 return pages; 238 } 239 240 public boolean add( 242 Page page 243 ) 244 {return commonAddAll(-1,Arrays.asList(page));} 245 246 public boolean addAll( 247 Collection <? extends Page> pages 248 ) 249 {return commonAddAll(-1,pages);} 250 251 public void clear( 252 ) 253 {throw new NotImplementedException();} 254 255 public boolean contains( 256 Object page 257 ) 258 {throw new NotImplementedException();} 259 260 public boolean containsAll( 261 Collection <?> pages 262 ) 263 {throw new NotImplementedException();} 264 265 public boolean equals( 266 Object object 267 ) 268 {throw new NotImplementedException();} 269 270 public int hashCode( 271 ) 272 {throw new NotImplementedException();} 273 274 public boolean isEmpty( 275 ) 276 {throw new NotImplementedException();} 277 278 public boolean remove( 279 Object page 280 ) 281 { 282 Page pageObj = (Page)page; 283 PdfDictionary pageData = pageObj.getBaseDataObject(); 284 PdfDirectObject parent = pageData.get(PdfName.Parent); 286 PdfDictionary parentData = (PdfDictionary)File.resolve(parent); 287 PdfDirectObject kids = parentData.get(PdfName.Kids); 289 PdfArray kidsData = (PdfArray)File.resolve(kids); 290 kidsData.remove(pageObj.getBaseObject()); 292 boolean updateParent = !File.update(kids); pageData.put(PdfName.Parent,null); 295 pageObj.update(); 296 do 298 { 299 PdfDirectObject count = parentData.get(PdfName.Count); 301 IPdfNumber countData = (IPdfNumber)File.resolve(count); 302 countData.translateNumberValue(-1); 304 updateParent |= !File.update(count); 310 if(updateParent) 311 { 312 File.update(parent); 313 updateParent = false; } 315 316 parent = parentData.get(PdfName.Parent); 318 parentData = (PdfDictionary)File.resolve(parent); 319 } while(parent != null); 320 321 return true; 322 } 323 324 public boolean removeAll( 325 Collection <?> pages 326 ) 327 { 328 333 boolean changed = false; 334 for(Object page : pages) 335 {changed |= remove(page);} 336 337 return changed; 338 } 339 340 public boolean retainAll( 341 Collection <?> pages 342 ) 343 {throw new NotImplementedException();} 344 345 public int size( 346 ) 347 {return ((PdfInteger)getBaseDataObject().get(PdfName.Count)).getValue();} 348 349 public Page[] toArray( 350 ) 351 {throw new NotImplementedException();} 352 353 public <Page> Page[] toArray( 354 Page[] pages 355 ) 356 {throw new NotImplementedException();} 357 358 public Iterator <Page> iterator( 360 ) 361 { 362 return new Iterator <Page>() 363 { 364 370 private int index = 0; 371 374 private int size = size(); 375 376 379 private int levelIndex = 0; 380 383 private Stack <Integer > levelIndexes = new Stack <Integer >(); 384 387 private PdfDictionary parent = getBaseDataObject(); 388 391 private PdfArray kids = (PdfArray)File.resolve(parent.get(PdfName.Kids)); 392 394 public boolean hasNext( 398 ) 399 {return (index < size);} 400 401 public Page next( 402 ) 403 { 404 if(!hasNext()) 405 throw new NoSuchElementException (); 406 407 return getNext(); 408 } 409 410 public void remove( 411 ) 412 {throw new UnsupportedOperationException ();} 413 416 private Page getNext( 418 ) 419 { 420 427 436 while(true) 437 { 438 if(kids.size() == levelIndex) { 441 levelIndex = levelIndexes.pop() + 1; parent = (PdfDictionary)File.resolve(parent.get(PdfName.Parent)); 446 kids = (PdfArray)File.resolve(parent.get(PdfName.Kids)); 447 } 448 else { 450 PdfReference kidReference = (PdfReference)kids.get(levelIndex); 451 PdfDictionary kid = (PdfDictionary)File.resolve(kidReference); 452 if(kid.get(PdfName.Type).equals(PdfName.Page)) { 455 index++; levelIndex++; 459 return new Page(kidReference); 460 } 461 else { 463 levelIndexes.push(levelIndex); 466 parent = kid; 468 kids = (PdfArray)File.resolve(parent.get(PdfName.Kids)); 469 levelIndex = 0; } 471 } 472 } 473 } 474 }; 479 } 480 485 491 private boolean commonAddAll( 492 int index, 493 Collection <? extends Page> pages 494 ) 495 { 496 PdfDirectObject parent; 497 PdfDictionary parentData; 498 PdfDirectObject kids; 499 PdfArray kidsData; 500 int offset; 501 if(index == -1) { 504 parent = getBaseObject(); 506 parentData = getBaseDataObject(); 507 kids = parentData.get(PdfName.Kids); 509 kidsData = (PdfArray)File.resolve(kids); 510 offset = 0; } 512 else { 514 Page pivotPage = get(index); 516 parent = pivotPage.getBaseDataObject().get(PdfName.Parent); 518 parentData = (PdfDictionary)File.resolve(parent); 519 kids = parentData.get(PdfName.Kids); 521 kidsData = (PdfArray)File.resolve(kids); 522 offset = kidsData.indexOf(pivotPage.getBaseObject()); 524 } 525 526 for(Page page : pages) 528 { 529 if(index == -1) { 532 kidsData.add(page.getBaseObject()); 534 } 535 else { 537 kidsData.add( 539 offset++, 540 page.getBaseObject() 541 ); 542 } 543 page.getBaseDataObject().put(PdfName.Parent,parent); 545 page.update(); 546 } 547 boolean updateParent = !File.update(kids); 549 do 551 { 552 PdfDirectObject count = parentData.get(PdfName.Count); 554 IPdfNumber countData = (IPdfNumber)File.resolve(count); 555 countData.translateNumberValue(pages.size()); 557 updateParent |= !File.update(count); 563 if(updateParent) 564 { 565 File.update(parent); 566 updateParent = false; } 568 569 parent = parentData.get(PdfName.Parent); 571 parentData = (PdfDictionary)File.resolve(parent); 572 } while(parent != null); 573 574 return true; 575 } 576 } | Popular Tags |