001: /*
002: Copyright © 2007 Stefano Chizzolini. http://clown.stefanochizzolini.it
003:
004: Contributors:
005: * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it):
006: contributed code is Copyright © 2007 by Stefano Chizzolini.
007:
008: This file should be part of the source code distribution of "PDF Clown library"
009: (the Program): see the accompanying README files for more info.
010:
011: This Program is free software; you can redistribute it and/or modify it under
012: the terms of the GNU General Public License as published by the Free Software
013: Foundation; either version 2 of the License, or (at your option) any later version.
014:
015: This Program is distributed in the hope that it will be useful, but WITHOUT ANY
016: WARRANTY, either expressed or implied; without even the implied warranty of
017: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
018:
019: You should have received a copy of the GNU General Public License along with this
020: Program (see README files); if not, go to the GNU website (http://www.gnu.org/).
021:
022: Redistribution and use, with or without modification, are permitted provided that such
023: redistributions retain the above copyright notice, license and disclaimer, along with
024: this list of conditions.
025: */
026:
027: package it.stefanochizzolini.clown.documents.contents;
028:
029: import it.stefanochizzolini.clown.bytes.IBuffer;
030: import it.stefanochizzolini.clown.documents.Document;
031: import it.stefanochizzolini.clown.documents.Page;
032: import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
033: import it.stefanochizzolini.clown.documents.contents.objects.Operation;
034: import it.stefanochizzolini.clown.documents.contents.objects.InlineImage;
035: import it.stefanochizzolini.clown.documents.contents.objects.LocalGraphicsState;
036: import it.stefanochizzolini.clown.documents.contents.objects.ShadingObject;
037: import it.stefanochizzolini.clown.documents.contents.objects.Text;
038: import it.stefanochizzolini.clown.documents.contents.objects.XObject;
039: import it.stefanochizzolini.clown.documents.contents.tokens.Parser;
040: import it.stefanochizzolini.clown.files.File;
041: import it.stefanochizzolini.clown.objects.PdfArray;
042: import it.stefanochizzolini.clown.objects.PdfDataObject;
043: import it.stefanochizzolini.clown.objects.PdfDirectObject;
044: import it.stefanochizzolini.clown.objects.PdfIndirectObject;
045: import it.stefanochizzolini.clown.objects.PdfObjectWrapper;
046: import it.stefanochizzolini.clown.objects.PdfReference;
047: import it.stefanochizzolini.clown.objects.PdfStream;
048: import it.stefanochizzolini.clown.tokens.FileFormatException;
049: import it.stefanochizzolini.clown.util.NotImplementedException;
050:
051: import java.util.ArrayList;
052: import java.util.Collection;
053: import java.util.Iterator;
054: import java.util.List;
055: import java.util.ListIterator;
056:
057: /**
058: Content objects collection.
059:
060: @author Stefano Chizzolini
061: @version 0.0.5
062: @since 0.0.4
063: */
064: public class Contents extends PdfObjectWrapper<PdfDataObject> implements
065: List<ContentObject> {
066: // <class>
067: // <dynamic>
068: // <fields>
069: private List<ContentObject> items;
070:
071: private IContentContext contentContext;
072:
073: // </fields>
074:
075: // <constructors>
076: /**
077: <h3>Remarks</h3>
078: <p>For internal use only.</p>
079: */
080: public Contents(PdfDirectObject baseObject,
081: PdfIndirectObject container, IContentContext contentContext) {
082: super (baseObject, container);
083:
084: this .contentContext = contentContext;
085:
086: load();
087: }
088:
089: // </constructors>
090:
091: // <interface>
092: // <public>
093: @Override
094: public Contents clone(Document context) {
095: throw new NotImplementedException();
096: }
097:
098: /**
099: Serializes the contents into the content stream.
100: @version 0.0.5
101: */
102: public void flush() {
103: PdfStream stream;
104: PdfDataObject baseDataObject = getBaseDataObject();
105: // Are contents just a single stream object?
106: if (baseDataObject instanceof PdfStream) // Single stream.
107: {
108: stream = (PdfStream) baseDataObject;
109: } else // Array of streams.
110: {
111: PdfArray streams = (PdfArray) baseDataObject;
112: // No stream available?
113: if (streams.size() == 0) // No stream.
114: {
115: // Add first stream!
116: stream = new PdfStream();
117: streams.add( // Inserts the new stream into the content stream.
118: getFile().register(stream) // Inserts the new stream into the file.
119: );
120: } else // Streams exist.
121: {
122: // Eliminating exceeding streams...
123: /*
124: NOTE: Applications that consume or produce PDF files are not required to preserve
125: the existing structure of the Contents array [PDF:1.6:3.6.2].
126: */
127: while (streams.size() > 1) {
128: getFile().unregister( // Removes the exceeding stream from the file.
129: (PdfReference) streams.remove(1) // Removes the exceeding stream from the content stream.
130: );
131: }
132:
133: PdfReference streamReference = (PdfReference) streams
134: .get(0);
135: File.update(streamReference); // Updates the existing stream into the file.
136: stream = (PdfStream) streamReference.getDataObject();
137: }
138: }
139:
140: // Get the stream buffer!
141: IBuffer buffer = stream.getBody();
142: // Delete old contents from the stream buffer!
143: buffer.setLength(0);
144: // Serializing the new contents into the stream buffer...
145: for (ContentObject item : items) {
146: item.writeTo(buffer);
147: }
148:
149: // Update the content stream container!
150: update();
151: }
152:
153: public IContentContext getContentContext() {
154: return contentContext;
155: }
156:
157: // <List>
158: public void add(int index, ContentObject content) {
159: items.add(index, content);
160: }
161:
162: public boolean addAll(int index,
163: Collection<? extends ContentObject> contents) {
164: return items.addAll(index, contents);
165: }
166:
167: public ContentObject get(int index) {
168: return items.get(index);
169: }
170:
171: public int indexOf(Object content) {
172: return items.indexOf(content);
173: }
174:
175: public int lastIndexOf(Object content) {
176: return items.lastIndexOf(content);
177: }
178:
179: public ListIterator<ContentObject> listIterator() {
180: return items.listIterator();
181: }
182:
183: public ListIterator<ContentObject> listIterator(int index) {
184: return items.listIterator(index);
185: }
186:
187: public ContentObject remove(int index) {
188: return items.remove(index);
189: }
190:
191: public ContentObject set(int index, ContentObject content) {
192: return items.set(index, content);
193: }
194:
195: public List<ContentObject> subList(int fromIndex, int toIndex) {
196: return items.subList(fromIndex, toIndex);
197: }
198:
199: // <Collection>
200: public boolean add(ContentObject content) {
201: return items.add(content);
202: }
203:
204: public boolean addAll(Collection<? extends ContentObject> contents) {
205: return items.addAll(contents);
206: }
207:
208: public void clear() {
209: items.clear();
210: }
211:
212: public boolean contains(Object content) {
213: return items.contains(content);
214: }
215:
216: public boolean containsAll(Collection<?> contents) {
217: return items.containsAll(contents);
218: }
219:
220: public boolean equals(Object object) {
221: throw new NotImplementedException();
222: }
223:
224: public int hashCode() {
225: throw new NotImplementedException();
226: }
227:
228: public boolean isEmpty() {
229: return items.isEmpty();
230: }
231:
232: public boolean remove(Object content) {
233: return items.remove(content);
234: }
235:
236: public boolean removeAll(Collection<?> contents) {
237: return items.removeAll(contents);
238: }
239:
240: public boolean retainAll(Collection<?> contents) {
241: return items.retainAll(contents);
242: }
243:
244: public int size() {
245: return items.size();
246: }
247:
248: public Object[] toArray() {
249: return items.toArray();
250: }
251:
252: public <ContentObject> ContentObject[] toArray(
253: ContentObject[] contents) {
254: return items.toArray(contents);
255: }
256:
257: // <Iterable>
258: public Iterator<ContentObject> iterator() {
259: return items.iterator();
260: }
261:
262: // </Iterable>
263: // </Collection>
264: // </List>
265: // </public>
266:
267: // <private>
268: private void load() {
269: final Parser parser = new Parser(getBaseDataObject());
270: try {
271: items = parser.parseContentObjects();
272: } catch (Exception e) {
273: throw new RuntimeException(e);
274: }
275: }
276: // </private>
277: // </interface>
278: // </dynamic>
279: // </class>
280: }
|