001: /**
002: * Copyright (c) 2003-2005, www.pdfbox.org
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions are met:
007: *
008: * 1. Redistributions of source code must retain the above copyright notice,
009: * this list of conditions and the following disclaimer.
010: * 2. Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: * 3. Neither the name of pdfbox; nor the names of its
014: * contributors may be used to endorse or promote products derived from this
015: * software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
021: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: *
028: * http://www.pdfbox.org
029: *
030: */package org.pdfbox.pdmodel;
031:
032: import java.io.IOException;
033:
034: import java.util.HashMap;
035: import java.util.Iterator;
036: import java.util.Map;
037:
038: import org.pdfbox.cos.COSBase;
039: import org.pdfbox.cos.COSDictionary;
040: import org.pdfbox.cos.COSName;
041: import org.pdfbox.cos.COSStream;
042:
043: import org.pdfbox.pdmodel.common.COSDictionaryMap;
044: import org.pdfbox.pdmodel.common.COSObjectable;
045:
046: import org.pdfbox.pdmodel.font.PDFontFactory;
047:
048: import org.pdfbox.pdmodel.graphics.PDExtendedGraphicsState;
049:
050: import org.pdfbox.pdmodel.graphics.color.PDColorSpaceFactory;
051:
052: import org.pdfbox.pdmodel.graphics.xobject.PDXObject;
053: import org.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;
054:
055: /**
056: * This represents a set of resources available at the page/pages/stream level.
057: *
058: * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
059: * @version $Revision: 1.16 $
060: */
061: public class PDResources implements COSObjectable {
062: private COSDictionary resources;
063:
064: /**
065: * Default constructor.
066: */
067: public PDResources() {
068: resources = new COSDictionary();
069: }
070:
071: /**
072: * Prepopulated resources.
073: *
074: * @param resourceDictionary The cos dictionary for this resource.
075: */
076: public PDResources(COSDictionary resourceDictionary) {
077: resources = resourceDictionary;
078: }
079:
080: /**
081: * This will get the underlying dictionary.
082: *
083: * @return The dictionary for these resources.
084: */
085: public COSDictionary getCOSDictionary() {
086: return resources;
087: }
088:
089: /**
090: * Convert this standard java object to a COS object.
091: *
092: * @return The cos object that matches this Java object.
093: */
094: public COSBase getCOSObject() {
095: return resources;
096: }
097:
098: /**
099: * This will get the map of fonts. This will never return null. The keys are string
100: * and the values are PDFont objects.
101: *
102: * @param fontCache A map of existing PDFont objects to reuse.
103: * @return The map of fonts.
104: *
105: * @throws IOException If there is an error getting the fonts.
106: */
107: public Map getFonts(Map fontCache) throws IOException {
108: Map retval = null;
109: COSDictionary fonts = (COSDictionary) resources
110: .getDictionaryObject(COSName.FONT);
111:
112: if (fonts == null) {
113: fonts = new COSDictionary();
114: resources.setItem(COSName.FONT, fonts);
115: }
116:
117: Map actuals = new HashMap();
118: retval = new COSDictionaryMap(actuals, fonts);
119: Iterator fontNames = fonts.keyList().iterator();
120: while (fontNames.hasNext()) {
121: COSName fontName = (COSName) fontNames.next();
122: COSBase font = fonts.getDictionaryObject(fontName);
123: //data-000174.pdf contains a font that is a COSArray, looks to be an error in the
124: //PDF, we will just ignore entries that are not dictionaries.
125: if (font instanceof COSDictionary) {
126: COSDictionary fontDictionary = (COSDictionary) font;
127: actuals.put(fontName.getName(), PDFontFactory
128: .createFont(fontDictionary, fontCache));
129: }
130: }
131: return retval;
132: }
133:
134: /**
135: * This will get the map of fonts. This will never return null. The keys are string
136: * and the values are PDFont objects.
137: *
138: * @return The map of fonts.
139: *
140: * @throws IOException If there is an error getting the fonts.
141: */
142: public Map getFonts() throws IOException {
143: return getFonts(null);
144: }
145:
146: /**
147: * This will get the map of PDXObjects that are in the resource dictionary.
148: *
149: * @return The map of xobjects.
150: *
151: * @throws IOException If there is an error creating the xobjects.
152: */
153: public Map getXObjects() throws IOException {
154: Map retval = null;
155: COSDictionary xobjects = (COSDictionary) resources
156: .getDictionaryObject("XObject");
157:
158: if (xobjects == null) {
159: xobjects = new COSDictionary();
160: resources.setItem("XObject", xobjects);
161: }
162:
163: Map actuals = new HashMap();
164: retval = new COSDictionaryMap(actuals, xobjects);
165: Iterator imageNames = xobjects.keyList().iterator();
166: while (imageNames.hasNext()) {
167: COSName objName = (COSName) imageNames.next();
168: COSBase cosObject = xobjects.getDictionaryObject(objName);
169: PDXObject xobject = PDXObject.createXObject(cosObject);
170: if (xobject != null) {
171: actuals.put(objName.getName(), xobject);
172: }
173: }
174: return retval;
175: }
176:
177: /**
178: * This will get the map of images. An empty map will be returned if there
179: * are no underlying images.
180: * So far the keys are COSName of the image
181: * and the value is the corresponding PDXObjectImage.
182: *
183: * @author By BM
184: * @return The map of images.
185: * @throws IOException If there is an error writing the picture.
186: */
187: public Map getImages() throws IOException {
188: Map retval = null;
189: COSDictionary images = (COSDictionary) resources
190: .getDictionaryObject("XObject");
191:
192: if (images == null) {
193: images = new COSDictionary();
194: resources.setItem("XObject", images);
195: }
196:
197: Map actuals = new HashMap();
198: retval = new COSDictionaryMap(actuals, images);
199: Iterator imageNames = images.keyList().iterator();
200: while (imageNames.hasNext()) {
201: COSName imageName = (COSName) imageNames.next();
202: COSStream image = (COSStream) (images
203: .getDictionaryObject(imageName));
204:
205: COSName subType = (COSName) image
206: .getDictionaryObject(COSName.SUBTYPE);
207: if (subType.equals(COSName.IMAGE)) {
208: PDXObjectImage ximage = (PDXObjectImage) PDXObject
209: .createXObject(image);
210: if (ximage != null) {
211: actuals.put(imageName.getName(), ximage);
212: }
213: }
214: }
215: return retval;
216: }
217:
218: /**
219: * This will set the map of fonts.
220: *
221: * @param fonts The new map of fonts.
222: */
223: public void setFonts(Map fonts) {
224: resources
225: .setItem(COSName.FONT, COSDictionaryMap.convert(fonts));
226: }
227:
228: /**
229: * This will get the map of colorspaces. This will return null if the underlying
230: * resources dictionary does not have a colorspace dictionary. The keys are string
231: * and the values are PDColorSpace objects.
232: *
233: * @return The map of colorspaces.
234: *
235: * @throws IOException If there is an error getting the colorspaces.
236: */
237: public Map getColorSpaces() throws IOException {
238: Map retval = null;
239: COSDictionary colorspaces = (COSDictionary) resources
240: .getDictionaryObject(COSName.getPDFName("ColorSpace"));
241:
242: if (colorspaces != null) {
243: Map actuals = new HashMap();
244: retval = new COSDictionaryMap(actuals, colorspaces);
245: Iterator csNames = colorspaces.keyList().iterator();
246: while (csNames.hasNext()) {
247: COSName csName = (COSName) csNames.next();
248: COSBase cs = colorspaces.getDictionaryObject(csName);
249: actuals.put(csName.getName(), PDColorSpaceFactory
250: .createColorSpace(cs));
251: }
252: }
253: return retval;
254: }
255:
256: /**
257: * This will set the map of colorspaces.
258: *
259: * @param colorspaces The new map of colorspaces.
260: */
261: public void setColorSpaces(Map colorspaces) {
262: resources.setItem(COSName.getPDFName("ColorSpace"),
263: COSDictionaryMap.convert(colorspaces));
264: }
265:
266: /**
267: * This will get the map of graphic states. This will return null if the underlying
268: * resources dictionary does not have a graphics dictionary. The keys are the graphic state
269: * name as a String and the values are PDExtendedGraphicsState objects.
270: *
271: * @return The map of extended graphic state objects.
272: */
273: public Map getGraphicsStates() {
274: Map retval = null;
275: COSDictionary states = (COSDictionary) resources
276: .getDictionaryObject(COSName.getPDFName("ExtGState"));
277:
278: if (states != null) {
279: Map actuals = new HashMap();
280: retval = new COSDictionaryMap(actuals, states);
281: Iterator names = states.keyList().iterator();
282: while (names.hasNext()) {
283: COSName name = (COSName) names.next();
284: COSDictionary dictionary = (COSDictionary) states
285: .getDictionaryObject(name);
286: actuals.put(name.getName(),
287: new PDExtendedGraphicsState(dictionary));
288: }
289: }
290: return retval;
291: }
292:
293: /**
294: * This will set the map of graphics states.
295: *
296: * @param states The new map of states.
297: */
298: public void setGraphicsStates(Map states) {
299: Iterator iter = states.keySet().iterator();
300: COSDictionary dic = new COSDictionary();
301: while (iter.hasNext()) {
302: String name = (String) iter.next();
303: PDExtendedGraphicsState state = (PDExtendedGraphicsState) states
304: .get(name);
305: dic.setItem(COSName.getPDFName(name), state.getCOSObject());
306: }
307: resources.setItem(COSName.getPDFName("ExtGState"), dic);
308: }
309: }
|