001/*
002 * $Id: PageResources.java 4784 2011-03-15 08:33:00Z blowagie $
003 *
004 * This file is part of the iText (R) project.
005 * Copyright (c) 1998-2011 1T3XT BVBA
006 * Authors: Bruno Lowagie, Paulo Soares, et al.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU Affero General Public License version 3
010 * as published by the Free Software Foundation with the addition of the
011 * following permission added to Section 15 as permitted in Section 7(a):
012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT,
013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
014 *
015 * This program is distributed in the hope that it will be useful, but
016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
017 * or FITNESS FOR A PARTICULAR PURPOSE.
018 * See the GNU Affero General Public License for more details.
019 * You should have received a copy of the GNU Affero General Public License
020 * along with this program; if not, see http://www.gnu.org/licenses or write to
021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
022 * Boston, MA, 02110-1301 USA, or download the license from the following URL:
023 * http://itextpdf.com/terms-of-use/
024 *
025 * The interactive user interfaces in modified source and object code versions
026 * of this program must display Appropriate Legal Notices, as required under
027 * Section 5 of the GNU Affero General Public License.
028 *
029 * In accordance with Section 7(b) of the GNU Affero General Public License,
030 * a covered work must retain the producer line in every PDF that is created
031 * or manipulated using iText.
032 *
033 * You can be released from the requirements of the license by purchasing
034 * a commercial license. Buying such a license is mandatory as soon as you
035 * develop commercial activities involving the iText software without
036 * disclosing the source code of your own applications.
037 * These activities include: offering paid services to customers as an ASP,
038 * serving PDFs on the fly in a web application, shipping iText with a closed
039 * source product.
040 *
041 * For more information, please contact iText Software Corp. at this
042 * address: sales@itextpdf.com
043 */
044package com.itextpdf.text.pdf;
045
046import java.util.HashMap;
047import java.util.HashSet;
048
049class PageResources {
050
051    protected PdfDictionary fontDictionary = new PdfDictionary();
052    protected PdfDictionary xObjectDictionary = new PdfDictionary();
053    protected PdfDictionary colorDictionary = new PdfDictionary();
054    protected PdfDictionary patternDictionary = new PdfDictionary();
055    protected PdfDictionary shadingDictionary = new PdfDictionary();
056    protected PdfDictionary extGStateDictionary = new PdfDictionary();
057    protected PdfDictionary propertyDictionary = new PdfDictionary();
058    protected HashSet<PdfName> forbiddenNames;
059    protected PdfDictionary originalResources;
060    protected int namePtr[] = {0};
061    protected HashMap<PdfName, PdfName> usedNames;
062
063    PageResources() {
064    }
065
066    void setOriginalResources(PdfDictionary resources, int newNamePtr[]) {
067        if (newNamePtr != null)
068            namePtr = newNamePtr;
069        forbiddenNames = new HashSet<PdfName>();
070        usedNames = new HashMap<PdfName, PdfName>();
071        if (resources == null)
072            return;
073        originalResources = new PdfDictionary();
074        originalResources.merge(resources);
075        for (Object element : resources.getKeys()) {
076            PdfName key = (PdfName)element;
077            PdfObject sub = PdfReader.getPdfObject(resources.get(key));
078            if (sub != null && sub.isDictionary()) {
079                PdfDictionary dic = (PdfDictionary)sub;
080                for (PdfName element2 : dic.getKeys()) {
081                    forbiddenNames.add(element2);
082                }
083                PdfDictionary dic2 = new PdfDictionary();
084                dic2.merge(dic);
085                originalResources.put(key, dic2);
086            }
087        }
088    }
089
090    PdfName translateName(PdfName name) {
091        PdfName translated = name;
092        if (forbiddenNames != null) {
093            translated = usedNames.get(name);
094            if (translated == null) {
095                while (true) {
096                    translated = new PdfName("Xi" + namePtr[0]++);
097                    if (!forbiddenNames.contains(translated))
098                        break;
099                }
100                usedNames.put(name, translated);
101            }
102        }
103        return translated;
104    }
105
106    PdfName addFont(PdfName name, PdfIndirectReference reference) {
107        name = translateName(name);
108        fontDictionary.put(name, reference);
109        return name;
110    }
111
112    PdfName addXObject(PdfName name, PdfIndirectReference reference) {
113        name = translateName(name);
114        xObjectDictionary.put(name, reference);
115        return name;
116    }
117
118    PdfName addColor(PdfName name, PdfIndirectReference reference) {
119        name = translateName(name);
120        colorDictionary.put(name, reference);
121        return name;
122    }
123
124    void addDefaultColor(PdfName name, PdfObject obj) {
125        if (obj == null || obj.isNull())
126            colorDictionary.remove(name);
127        else
128            colorDictionary.put(name, obj);
129    }
130
131    void addDefaultColor(PdfDictionary dic) {
132        colorDictionary.merge(dic);
133    }
134
135    void addDefaultColorDiff(PdfDictionary dic) {
136        colorDictionary.mergeDifferent(dic);
137    }
138
139    PdfName addShading(PdfName name, PdfIndirectReference reference) {
140        name = translateName(name);
141        shadingDictionary.put(name, reference);
142        return name;
143    }
144
145    PdfName addPattern(PdfName name, PdfIndirectReference reference) {
146        name = translateName(name);
147        patternDictionary.put(name, reference);
148        return name;
149    }
150
151    PdfName addExtGState(PdfName name, PdfIndirectReference reference) {
152        name = translateName(name);
153        extGStateDictionary.put(name, reference);
154        return name;
155    }
156
157    PdfName addProperty(PdfName name, PdfIndirectReference reference) {
158        name = translateName(name);
159        propertyDictionary.put(name, reference);
160        return name;
161    }
162
163    PdfDictionary getResources() {
164       PdfResources resources = new PdfResources();
165        if (originalResources != null)
166            resources.putAll(originalResources);
167        resources.put(PdfName.PROCSET, new PdfLiteral("[/PDF /Text /ImageB /ImageC /ImageI]"));
168        resources.add(PdfName.FONT, fontDictionary);
169        resources.add(PdfName.XOBJECT, xObjectDictionary);
170        resources.add(PdfName.COLORSPACE, colorDictionary);
171        resources.add(PdfName.PATTERN, patternDictionary);
172        resources.add(PdfName.SHADING, shadingDictionary);
173        resources.add(PdfName.EXTGSTATE, extGStateDictionary);
174        resources.add(PdfName.PROPERTIES, propertyDictionary);
175        return resources;
176    }
177
178    boolean hasResources() {
179        return fontDictionary.size() > 0
180            || xObjectDictionary.size() > 0
181            || colorDictionary.size() > 0
182            || patternDictionary.size() > 0
183            || shadingDictionary.size() > 0
184            || extGStateDictionary.size() > 0
185            || propertyDictionary.size() > 0;
186    }
187}