001: /*
002: * Copyright (c) 2007, intarsys consulting GmbH
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * - Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * - 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: *
014: * - Neither the name of intarsys nor the names of its contributors may be used
015: * to endorse or promote products derived from this software without specific
016: * prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028: * POSSIBILITY OF SUCH DAMAGE.
029: */
030: package de.intarsys.pdf.pd;
031:
032: import java.util.HashMap;
033: import java.util.Map;
034:
035: import de.intarsys.pdf.content.CSContent;
036: import de.intarsys.pdf.cos.COSBasedObject;
037: import de.intarsys.pdf.cos.COSDictionary;
038: import de.intarsys.pdf.cos.COSName;
039: import de.intarsys.pdf.cos.COSNull;
040: import de.intarsys.pdf.cos.COSObject;
041: import de.intarsys.pdf.font.PDFont;
042:
043: /**
044: * The implementation of a resource dictionary.
045: *
046: * <p>
047: * The resource dictionary holds the references to indirect objects that are use
048: * within a {@link CSContent}. From the {@link CSContent}, these objects are
049: * referenced using the key under which they are stored in the dictionary.
050: * </p>
051: */
052: public class PDResources extends PDObject {
053: /**
054: * The meta class implementation
055: */
056: public static class MetaClass extends PDObject.MetaClass {
057: protected MetaClass(Class paramInstanceClass) {
058: super (paramInstanceClass);
059: }
060:
061: protected COSBasedObject doCreateCOSBasedObject(COSObject object) {
062: return new PDResources(object);
063: }
064: }
065:
066: public static final COSName CN_RT_ColorSpace = COSName
067: .constant("ColorSpace"); //$NON-NLS-1$
068:
069: public static final COSName CN_RT_Encoding = COSName
070: .constant("Encoding"); //$NON-NLS-1$
071:
072: /** the resource types in a resource dictionaries */
073: public static final COSName CN_RT_ExtGState = COSName
074: .constant("ExtGState"); //$NON-NLS-1$
075:
076: public static final COSName CN_RT_Font = COSName.constant("Font"); //$NON-NLS-1$
077:
078: public static final COSName CN_RT_Pattern = COSName
079: .constant("Pattern"); //$NON-NLS-1$
080:
081: public static final COSName CN_RT_ProcSet = COSName
082: .constant("ProcSet"); //$NON-NLS-1$
083:
084: public static final COSName CN_RT_Properties = COSName
085: .constant("Properties"); //$NON-NLS-1$
086:
087: public static final COSName CN_RT_Shading = COSName
088: .constant("Shading"); //$NON-NLS-1$
089:
090: public static final COSName CN_RT_XObject = COSName
091: .constant("XObject"); //$NON-NLS-1$
092:
093: /** The meta class instance */
094: public static final MetaClass META = new MetaClass(MetaClass.class
095: .getDeclaringClass());
096:
097: private static Map resourceNamePrefixes = new HashMap();
098:
099: static {
100: resourceNamePrefixes.put(CN_RT_ColorSpace, "CS"); //$NON-NLS-1$
101: resourceNamePrefixes.put(CN_RT_ExtGState, "GS"); //$NON-NLS-1$
102: resourceNamePrefixes.put(CN_RT_Font, "F"); //$NON-NLS-1$
103: resourceNamePrefixes.put(CN_RT_Pattern, "P"); //$NON-NLS-1$
104: resourceNamePrefixes.put(CN_RT_Shading, "S"); //$NON-NLS-1$
105: resourceNamePrefixes.put(CN_RT_XObject, "X"); //$NON-NLS-1$
106: }
107:
108: private Map currentCounters = new HashMap();
109:
110: /** a cached representation of the resources */
111: private Map cachedResources = new HashMap();
112:
113: /**
114: * Create a resource dictionary
115: *
116: * @param object
117: * The COS Object implementing the dictionary
118: */
119: protected PDResources(COSObject object) {
120: super (object);
121: }
122:
123: public void addColorSpaceResource(COSName name,
124: PDColorSpace colorSpace) {
125: addResource(CN_RT_ColorSpace, name, colorSpace);
126: }
127:
128: public void addExtGStateResource(COSName name, PDExtGState extGState) {
129: addResource(CN_RT_ExtGState, name, extGState);
130: }
131:
132: public void addFontResource(COSName name, PDFont font) {
133: addResource(CN_RT_Font, name, font);
134: }
135:
136: public void addPatternResource(COSName name, PDPattern pattern) {
137: addResource(CN_RT_Pattern, name, pattern);
138: }
139:
140: public void addResource(COSName resourceType, COSName name,
141: PDObject object) {
142: COSDictionary dict = cosGetResources(resourceType);
143: if (dict == null) {
144: dict = cosInitResources(resourceType);
145: }
146: dict.put(name, object.cosGetObject());
147: }
148:
149: public void addShadingResource(COSName name, PDShading shading) {
150: addResource(CN_RT_Shading, name, shading);
151: }
152:
153: public void addXObjectResource(COSName name, PDXObject object) {
154: addResource(CN_RT_XObject, name, object);
155: }
156:
157: public void cosAddResource(COSName resourceType,
158: COSName resourceName, COSObject resource) {
159: COSDictionary dict = cosGetResources(resourceType);
160: if (dict == null) {
161: dict = cosInitResources(resourceType);
162: }
163: dict.put(resourceName, resource);
164: }
165:
166: public COSName cosCreateResource(COSName resourceType,
167: COSObject resource) {
168: COSDictionary resources = cosGetResources(resourceType);
169: if (resources == null) {
170: resources = cosInitResources(resourceType);
171: }
172: COSName key = resources.keyOf(resource).asName();
173: if (key == null) {
174: key = createResourceName(resourceType);
175: resources.put(key, resource);
176: }
177: return key;
178: }
179:
180: protected COSName createResourceName(COSName resourceType) {
181: Integer count = (Integer) currentCounters.get(resourceType);
182: if (count == null) {
183: count = new Integer(0);
184: }
185: String prefix = (String) resourceNamePrefixes.get(resourceType);
186: while (true) {
187: count = new Integer(count.intValue() + 1);
188: COSName newName = COSName.create((prefix + count)
189: .getBytes());
190: COSObject object = cosGetResource(resourceType, newName);
191: if (object.isNull()) {
192: currentCounters.put(resourceType, count);
193: return newName;
194: }
195: }
196: }
197:
198: public COSObject cosGetResource(COSName resourceType,
199: COSName resourceName) {
200: COSDictionary resources = cosGetResources(resourceType);
201: if (resources == null) {
202: return COSNull.NULL;
203: }
204: return resources.get(resourceName);
205: }
206:
207: public COSDictionary cosGetResources(COSName resourceType) {
208: COSDictionary resources = (COSDictionary) cachedResources
209: .get(resourceType);
210: if (resources == null) {
211: resources = cosGetField(resourceType).asDictionary();
212: cachedResources.put(resourceType, resources);
213: }
214: return resources;
215: }
216:
217: protected COSDictionary cosInitResources(COSName resourceType) {
218: COSDictionary resource = COSDictionary.create();
219: cosSetField(resourceType, resource);
220: return resource;
221: }
222:
223: /**
224: * Return the name of a ColorSpace resource within the resource dictionary.
225: *
226: * <p>
227: * A new entry is created if the resource is not found.
228: * </p>
229: *
230: * @param colorSpace
231: * The colorSpace to lookup.
232: *
233: * @return the name of a ColorSpace resource within the resource dictionary.
234: */
235: public COSName createColorSpaceResource(PDColorSpace colorSpace) {
236: return createResource(CN_RT_ColorSpace, colorSpace);
237: }
238:
239: /**
240: * Return the name of a ExtGState resource within the resource dictionary.
241: *
242: * <p>
243: * A new entry is created if the resource is not found.
244: * </p>
245: *
246: * @param gstate
247: * The gstate to lookup.
248: *
249: * @return the name of a ExtGState resource within the resource dictionary.
250: */
251: public COSName createExtGStateResource(PDExtGState gstate) {
252: return createResource(CN_RT_ExtGState, gstate);
253: }
254:
255: /**
256: * Return the name of the font resource within this resource dictionary.
257: *
258: * <p>
259: * A new entry is created if the resource is not found.
260: * </p>
261: *
262: * @param font
263: * The font whose name is looked up.
264: *
265: * @return the name of the font resource within this resource dictionary.
266: */
267: public COSName createFontResource(PDFont font) {
268: return createResource(CN_RT_Font, font);
269: }
270:
271: /**
272: * Return the name of a new resource of selected resource type within the
273: * resource dictionary.
274: *
275: * <p>
276: * A new entry is created if the resource is not found.
277: * </p>
278: *
279: * @param object
280: * The resource to lookup.
281: *
282: * @return The name of a resource within the resource dictionary.
283: */
284: public COSName createResource(COSName resourceType, PDObject object) {
285: return cosCreateResource(resourceType, object.cosGetObject());
286: }
287:
288: /**
289: * Return the name of a shading resource within the resource dictionary.
290: *
291: * <p>
292: * A new entry is created if the resource is not found.
293: * </p>
294: *
295: * @param shading
296: * The shading to lookup.
297: *
298: * @return The name of the resource within the resource dictionary.
299: */
300: public COSName createShadingResource(PDShading shading) {
301: return createResource(CN_RT_Shading, shading);
302: }
303:
304: /**
305: * Return the name of a XObject resource within the resource dictionary.
306: *
307: * <p>
308: * A new entry is created if the resource is not found.
309: * </p>
310: *
311: * @param xobject
312: * The object to lookup.
313: *
314: * @return the name of a XObject resource within the resource dictionary.
315: */
316: public COSName createXObjectResource(PDXObject xobject) {
317: return createResource(CN_RT_XObject, xobject);
318: }
319:
320: /**
321: * A named ColorSpace resource from the resource dictionary.
322: *
323: * @param name
324: * The name of the ColorSpace resource.
325: *
326: * @return A named ColorSpace resource from the resource dictionary.
327: */
328: public PDColorSpace getColorSpaceResource(COSName name) {
329: return (PDColorSpace) getResource(CN_RT_ColorSpace,
330: PDColorSpace.META, name);
331: }
332:
333: /**
334: * Return a named ExtGState resource from the resource dictionary.
335: *
336: * @param name
337: * The name of the ExtGState resource.
338: *
339: * @return a named ExtGState resource from the resource dictionary.
340: */
341: public PDExtGState getExtGStateResource(COSName name) {
342: return (PDExtGState) getResource(CN_RT_ExtGState,
343: PDExtGState.META, name);
344: }
345:
346: /**
347: * Return a named font resource.
348: *
349: * @param name
350: * The name of the font resource
351: *
352: * @return A named font resource from within the resource dictionary.
353: */
354: public PDFont getFontResource(COSName name) {
355: return (PDFont) getResource(CN_RT_Font, PDFont.META, name);
356: }
357:
358: /**
359: * Return a named Pattern resource from the resource dictionary.
360: *
361: * @param name
362: * The name of the Pattern resource.
363: *
364: * @return a named Pattern resource from the resource dictionary.
365: */
366: public PDPattern getPatternResource(COSName name) {
367: return (PDPattern) getResource(CN_RT_Pattern, PDPattern.META,
368: name);
369: }
370:
371: /**
372: * Return a named resource from the resource dictionary.
373: *
374: * @param name
375: * The name of the resource.
376: *
377: * @return a named resource from the resource dictionary.
378: */
379: public PDObject getResource(COSName resourceType,
380: PDObject.MetaClass metaClass, COSName name) {
381: COSDictionary resources = cosGetResources(resourceType);
382: if (resources == null) {
383: return null;
384: }
385: return (PDObject) metaClass.createFromCos(resources.get(name));
386: }
387:
388: /**
389: * Return a named Pattern resource from the resource dictionary.
390: *
391: * @param name
392: * The name of the Pattern resource.
393: *
394: * @return a named Pattern resource from the resource dictionary.
395: */
396: public PDShading getShadingResource(COSName name) {
397: return (PDShading) getResource(CN_RT_Shading, PDShading.META,
398: name);
399: }
400:
401: /**
402: * Return a named XObject resource from the resource dictionary.
403: *
404: * @param name
405: * The name of the XObject resource.
406: *
407: * @return a named XObject resource from the resource dictionary.
408: */
409: public PDXObject getXObjectResource(COSName name) {
410: return (PDXObject) getResource(CN_RT_XObject, PDXObject.META,
411: name);
412: }
413:
414: /*
415: * (non-Javadoc)
416: *
417: * @see de.intarsys.pdf.cos.COSBasedObject#invalidateCaches()
418: */
419: public void invalidateCaches() {
420: super.invalidateCaches();
421: cachedResources.clear();
422: }
423: }
|