Source Code Cross Referenced for PdfStamperImp.java in  » PDF » pdf-itext » com » lowagie » text » pdf » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » PDF » pdf itext » com.lowagie.text.pdf 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2003 by Paulo Soares.
0003:         *
0004:         * The contents of this file are subject to the Mozilla Public License Version 1.1
0005:         * (the "License"); you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at http://www.mozilla.org/MPL/
0007:         *
0008:         * Software distributed under the License is distributed on an "AS IS" basis,
0009:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
0010:         * for the specific language governing rights and limitations under the License.
0011:         *
0012:         * The Original Code is 'iText, a free JAVA-PDF library'.
0013:         *
0014:         * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
0015:         * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
0016:         * All Rights Reserved.
0017:         * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
0018:         * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
0019:         *
0020:         * Contributor(s): all the names of the contributors are added in the source code
0021:         * where applicable.
0022:         *
0023:         * Alternatively, the contents of this file may be used under the terms of the
0024:         * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
0025:         * provisions of LGPL are applicable instead of those above.  If you wish to
0026:         * allow use of your version of this file only under the terms of the LGPL
0027:         * License and not to allow others to use your version of this file under
0028:         * the MPL, indicate your decision by deleting the provisions above and
0029:         * replace them with the notice and other provisions required by the LGPL.
0030:         * If you do not delete the provisions above, a recipient may use your version
0031:         * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
0032:         *
0033:         * This library is free software; you can redistribute it and/or modify it
0034:         * under the terms of the MPL as stated above or under the terms of the GNU
0035:         * Library General Public License as published by the Free Software Foundation;
0036:         * either version 2 of the License, or any later version.
0037:         *
0038:         * This library is distributed in the hope that it will be useful, but WITHOUT
0039:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
0040:         * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
0041:         * details.
0042:         *
0043:         * If you didn't download this code from the following link, you should check if
0044:         * you aren't using an obsolete version:
0045:         * http://www.lowagie.com/iText/
0046:         */
0047:        package com.lowagie.text.pdf;
0048:
0049:        import java.io.IOException;
0050:        import java.io.OutputStream;
0051:        import java.util.ArrayList;
0052:        import java.util.HashMap;
0053:        import java.util.HashSet;
0054:        import java.util.Iterator;
0055:        import java.util.Map;
0056:
0057:        import com.lowagie.text.DocumentException;
0058:        import com.lowagie.text.ExceptionConverter;
0059:        import com.lowagie.text.Image;
0060:        import com.lowagie.text.Rectangle;
0061:        import com.lowagie.text.pdf.collection.PdfCollection;
0062:        import com.lowagie.text.pdf.interfaces.PdfViewerPreferences;
0063:        import com.lowagie.text.pdf.internal.PdfViewerPreferencesImp;
0064:
0065:        class PdfStamperImp extends PdfWriter {
0066:            HashMap readers2intrefs = new HashMap();
0067:            HashMap readers2file = new HashMap();
0068:            RandomAccessFileOrArray file;
0069:            PdfReader reader;
0070:            IntHashtable myXref = new IntHashtable();
0071:            /** Integer(page number) -> PageStamp */
0072:            HashMap pagesToContent = new HashMap();
0073:            boolean closed = false;
0074:            /** Holds value of property rotateContents. */
0075:            private boolean rotateContents = true;
0076:            protected AcroFields acroFields;
0077:            protected boolean flat = false;
0078:            protected boolean flatFreeText = false;
0079:            protected int namePtr[] = { 0 };
0080:            protected HashSet partialFlattening = new HashSet();
0081:            protected boolean useVp = false;
0082:            protected PdfViewerPreferencesImp viewerPreferences = new PdfViewerPreferencesImp();
0083:            protected HashMap fieldTemplates = new HashMap();
0084:            protected boolean fieldsAdded = false;
0085:            protected int sigFlags = 0;
0086:            protected boolean append;
0087:            protected IntHashtable marked;
0088:            protected int initialXrefSize;
0089:            protected PdfAction openAction;
0090:
0091:            /** Creates new PdfStamperImp.
0092:             * @param reader the read PDF
0093:             * @param os the output destination
0094:             * @param pdfVersion the new pdf version or '\0' to keep the same version as the original
0095:             * document
0096:             * @param append
0097:             * @throws DocumentException on error
0098:             * @throws IOException
0099:             */
0100:            PdfStamperImp(PdfReader reader, OutputStream os, char pdfVersion,
0101:                    boolean append) throws DocumentException, IOException {
0102:                super (new PdfDocument(), os);
0103:                if (!reader.isOpenedWithFullPermissions())
0104:                    throw new IllegalArgumentException(
0105:                            "PdfReader not opened with owner password");
0106:                if (reader.isTampered())
0107:                    throw new DocumentException(
0108:                            "The original document was reused. Read it again from file.");
0109:                reader.setTampered(true);
0110:                this .reader = reader;
0111:                file = reader.getSafeFile();
0112:                this .append = append;
0113:                if (append) {
0114:                    if (reader.isRebuilt())
0115:                        throw new DocumentException(
0116:                                "Append mode requires a document without errors even if recovery was possible.");
0117:                    if (reader.isEncrypted())
0118:                        crypto = new PdfEncryption(reader.getDecrypt());
0119:                    pdf_version.setAppendmode(true);
0120:                    file.reOpen();
0121:                    byte buf[] = new byte[8192];
0122:                    int n;
0123:                    while ((n = file.read(buf)) > 0)
0124:                        this .os.write(buf, 0, n);
0125:                    file.close();
0126:                    prevxref = reader.getLastXref();
0127:                    reader.setAppendable(true);
0128:                } else {
0129:                    if (pdfVersion == 0)
0130:                        super .setPdfVersion(reader.getPdfVersion());
0131:                    else
0132:                        super .setPdfVersion(pdfVersion);
0133:                }
0134:                super .open();
0135:                pdf.addWriter(this );
0136:                if (append) {
0137:                    body.setRefnum(reader.getXrefSize());
0138:                    marked = new IntHashtable();
0139:                    if (reader.isNewXrefType())
0140:                        fullCompression = true;
0141:                    if (reader.isHybridXref())
0142:                        fullCompression = false;
0143:                }
0144:                initialXrefSize = reader.getXrefSize();
0145:            }
0146:
0147:            void close(HashMap moreInfo) throws IOException {
0148:                if (closed)
0149:                    return;
0150:                if (useVp) {
0151:                    reader.setViewerPreferences(viewerPreferences);
0152:                    markUsed(reader.getTrailer().get(PdfName.ROOT));
0153:                }
0154:                if (flat)
0155:                    flatFields();
0156:                if (flatFreeText)
0157:                    flatFreeTextFields();
0158:                addFieldResources();
0159:                PdfDictionary acroForm = (PdfDictionary) PdfReader
0160:                        .getPdfObject(
0161:                                reader.getCatalog().get(PdfName.ACROFORM),
0162:                                reader.getCatalog());
0163:                if (acroFields != null && acroFields.getXfa().isChanged()) {
0164:                    markUsed(acroForm);
0165:                    if (!flat)
0166:                        acroFields.getXfa().setXfa(this );
0167:                }
0168:                if (sigFlags != 0) {
0169:                    if (acroForm != null) {
0170:                        acroForm.put(PdfName.SIGFLAGS, new PdfNumber(sigFlags));
0171:                        markUsed(acroForm);
0172:                    }
0173:                }
0174:                closed = true;
0175:                addSharedObjectsToBody();
0176:                setOutlines();
0177:                setJavaScript();
0178:                addFileAttachments();
0179:                PdfDictionary catalog = reader.getCatalog();
0180:                if (openAction != null) {
0181:                    catalog.put(PdfName.OPENACTION, openAction);
0182:                }
0183:                if (pdf.pageLabels != null)
0184:                    catalog.put(PdfName.PAGELABELS, pdf.pageLabels
0185:                            .getDictionary(this ));
0186:                byte[] altMetadata = xmpMetadata;
0187:                if (altMetadata == null) {
0188:                    PdfObject xmpo = PdfReader.getPdfObject(catalog
0189:                            .get(PdfName.METADATA));
0190:                    if (xmpo != null && xmpo.isStream()) {
0191:                        altMetadata = PdfReader
0192:                                .getStreamBytesRaw((PRStream) xmpo);
0193:                        PdfReader.killIndirect(xmpo);
0194:                    }
0195:                }
0196:                // if there is XMP data to add: add it
0197:                if (altMetadata != null) {
0198:                    PdfStream xmp = new PdfStream(altMetadata);
0199:                    xmp.put(PdfName.TYPE, PdfName.METADATA);
0200:                    xmp.put(PdfName.SUBTYPE, PdfName.XML);
0201:                    if (crypto != null && !crypto.isMetadataEncrypted()) {
0202:                        PdfArray ar = new PdfArray();
0203:                        ar.add(PdfName.CRYPT);
0204:                        xmp.put(PdfName.FILTER, ar);
0205:                    }
0206:                    catalog.put(PdfName.METADATA, body.add(xmp)
0207:                            .getIndirectReference());
0208:                    markUsed(catalog);
0209:                }
0210:                PRIndirectReference iInfo = null;
0211:                try {
0212:                    file.reOpen();
0213:                    alterContents();
0214:                    iInfo = (PRIndirectReference) reader.trailer
0215:                            .get(PdfName.INFO);
0216:                    int skip = -1;
0217:                    if (iInfo != null)
0218:                        skip = iInfo.getNumber();
0219:                    int rootN = ((PRIndirectReference) reader.trailer
0220:                            .get(PdfName.ROOT)).getNumber();
0221:                    if (append) {
0222:                        int keys[] = marked.getKeys();
0223:                        for (int k = 0; k < keys.length; ++k) {
0224:                            int j = keys[k];
0225:                            PdfObject obj = reader.getPdfObjectRelease(j);
0226:                            if (obj != null && skip != j && j < initialXrefSize) {
0227:                                addToBody(obj, j, j != rootN);
0228:                            }
0229:                        }
0230:                        for (int k = initialXrefSize; k < reader.getXrefSize(); ++k) {
0231:                            PdfObject obj = reader.getPdfObject(k);
0232:                            if (obj != null) {
0233:                                addToBody(obj, getNewObjectNumber(reader, k, 0));
0234:                            }
0235:                        }
0236:                    } else {
0237:                        for (int k = 1; k < reader.getXrefSize(); ++k) {
0238:                            PdfObject obj = reader.getPdfObjectRelease(k);
0239:                            if (obj != null && skip != k) {
0240:                                addToBody(obj,
0241:                                        getNewObjectNumber(reader, k, 0),
0242:                                        k != rootN);
0243:                            }
0244:                        }
0245:                    }
0246:                } finally {
0247:                    try {
0248:                        file.close();
0249:                    } catch (Exception e) {
0250:                        // empty on purpose
0251:                    }
0252:                }
0253:                PdfIndirectReference encryption = null;
0254:                PdfObject fileID = null;
0255:                if (crypto != null) {
0256:                    if (append) {
0257:                        encryption = reader.getCryptoRef();
0258:                    } else {
0259:                        PdfIndirectObject encryptionObject = addToBody(crypto
0260:                                .getEncryptionDictionary(), false);
0261:                        encryption = encryptionObject.getIndirectReference();
0262:                    }
0263:                    fileID = crypto.getFileID();
0264:                } else
0265:                    fileID = PdfEncryption.createInfoId(PdfEncryption
0266:                            .createDocumentId());
0267:                PRIndirectReference iRoot = (PRIndirectReference) reader.trailer
0268:                        .get(PdfName.ROOT);
0269:                PdfIndirectReference root = new PdfIndirectReference(0,
0270:                        getNewObjectNumber(reader, iRoot.getNumber(), 0));
0271:                PdfIndirectReference info = null;
0272:                PdfDictionary oldInfo = (PdfDictionary) PdfReader
0273:                        .getPdfObject(iInfo);
0274:                PdfDictionary newInfo = new PdfDictionary();
0275:                if (oldInfo != null) {
0276:                    for (Iterator i = oldInfo.getKeys().iterator(); i.hasNext();) {
0277:                        PdfName key = (PdfName) i.next();
0278:                        PdfObject value = PdfReader.getPdfObject(oldInfo
0279:                                .get(key));
0280:                        newInfo.put(key, value);
0281:                    }
0282:                }
0283:                if (moreInfo != null) {
0284:                    for (Iterator i = moreInfo.entrySet().iterator(); i
0285:                            .hasNext();) {
0286:                        Map.Entry entry = (Map.Entry) i.next();
0287:                        String key = (String) entry.getKey();
0288:                        PdfName keyName = new PdfName(key);
0289:                        String value = (String) entry.getValue();
0290:                        if (value == null)
0291:                            newInfo.remove(keyName);
0292:                        else
0293:                            newInfo.put(keyName, new PdfString(value,
0294:                                    PdfObject.TEXT_UNICODE));
0295:                    }
0296:                }
0297:                if (append) {
0298:                    if (iInfo == null)
0299:                        info = addToBody(newInfo, false).getIndirectReference();
0300:                    else
0301:                        info = addToBody(newInfo, iInfo.getNumber(), false)
0302:                                .getIndirectReference();
0303:                } else {
0304:                    if (!newInfo.getKeys().isEmpty())
0305:                        info = addToBody(newInfo, false).getIndirectReference();
0306:                }
0307:                // write the cross-reference table of the body
0308:                body.writeCrossReferenceTable(os, root, info, encryption,
0309:                        fileID, prevxref);
0310:                if (fullCompression) {
0311:                    os.write(getISOBytes("startxref\n"));
0312:                    os.write(getISOBytes(String.valueOf(body.offset())));
0313:                    os.write(getISOBytes("\n%%EOF\n"));
0314:                } else {
0315:                    PdfTrailer trailer = new PdfTrailer(body.size(), body
0316:                            .offset(), root, info, encryption, fileID, prevxref);
0317:                    trailer.toPdf(this , os);
0318:                }
0319:                os.flush();
0320:                if (isCloseStream())
0321:                    os.close();
0322:                reader.close();
0323:            }
0324:
0325:            void applyRotation(PdfDictionary pageN, ByteBuffer out) {
0326:                if (!rotateContents)
0327:                    return;
0328:                Rectangle page = reader.getPageSizeWithRotation(pageN);
0329:                int rotation = page.getRotation();
0330:                switch (rotation) {
0331:                case 90:
0332:                    out.append(PdfContents.ROTATE90);
0333:                    out.append(page.getTop());
0334:                    out.append(' ').append('0').append(PdfContents.ROTATEFINAL);
0335:                    break;
0336:                case 180:
0337:                    out.append(PdfContents.ROTATE180);
0338:                    out.append(page.getRight());
0339:                    out.append(' ');
0340:                    out.append(page.getTop());
0341:                    out.append(PdfContents.ROTATEFINAL);
0342:                    break;
0343:                case 270:
0344:                    out.append(PdfContents.ROTATE270);
0345:                    out.append('0').append(' ');
0346:                    out.append(page.getRight());
0347:                    out.append(PdfContents.ROTATEFINAL);
0348:                    break;
0349:                }
0350:            }
0351:
0352:            void alterContents() throws IOException {
0353:                for (Iterator i = pagesToContent.values().iterator(); i
0354:                        .hasNext();) {
0355:                    PageStamp ps = (PageStamp) i.next();
0356:                    PdfDictionary pageN = ps.pageN;
0357:                    markUsed(pageN);
0358:                    PdfArray ar = null;
0359:                    PdfObject content = PdfReader.getPdfObject(pageN
0360:                            .get(PdfName.CONTENTS), pageN);
0361:                    if (content == null) {
0362:                        ar = new PdfArray();
0363:                        pageN.put(PdfName.CONTENTS, ar);
0364:                    } else if (content.isArray()) {
0365:                        ar = (PdfArray) content;
0366:                        markUsed(ar);
0367:                    } else if (content.isStream()) {
0368:                        ar = new PdfArray();
0369:                        ar.add(pageN.get(PdfName.CONTENTS));
0370:                        pageN.put(PdfName.CONTENTS, ar);
0371:                    } else {
0372:                        ar = new PdfArray();
0373:                        pageN.put(PdfName.CONTENTS, ar);
0374:                    }
0375:                    ByteBuffer out = new ByteBuffer();
0376:                    if (ps.under != null) {
0377:                        out.append(PdfContents.SAVESTATE);
0378:                        applyRotation(pageN, out);
0379:                        out.append(ps.under.getInternalBuffer());
0380:                        out.append(PdfContents.RESTORESTATE);
0381:                    }
0382:                    if (ps.over != null)
0383:                        out.append(PdfContents.SAVESTATE);
0384:                    PdfStream stream = new PdfStream(out.toByteArray());
0385:                    stream.flateCompress();
0386:                    ar.addFirst(addToBody(stream).getIndirectReference());
0387:                    out.reset();
0388:                    if (ps.over != null) {
0389:                        out.append(' ');
0390:                        out.append(PdfContents.RESTORESTATE);
0391:                        out.append(PdfContents.SAVESTATE);
0392:                        applyRotation(pageN, out);
0393:                        out.append(ps.over.getInternalBuffer());
0394:                        out.append(PdfContents.RESTORESTATE);
0395:                        stream = new PdfStream(out.toByteArray());
0396:                        stream.flateCompress();
0397:                        ar.add(addToBody(stream).getIndirectReference());
0398:                    }
0399:                    alterResources(ps);
0400:                }
0401:            }
0402:
0403:            void alterResources(PageStamp ps) {
0404:                ps.pageN
0405:                        .put(PdfName.RESOURCES, ps.pageResources.getResources());
0406:            }
0407:
0408:            protected int getNewObjectNumber(PdfReader reader, int number,
0409:                    int generation) {
0410:                IntHashtable ref = (IntHashtable) readers2intrefs.get(reader);
0411:                if (ref != null) {
0412:                    int n = ref.get(number);
0413:                    if (n == 0) {
0414:                        n = getIndirectReferenceNumber();
0415:                        ref.put(number, n);
0416:                    }
0417:                    return n;
0418:                }
0419:                if (currentPdfReaderInstance == null) {
0420:                    if (append && number < initialXrefSize)
0421:                        return number;
0422:                    int n = myXref.get(number);
0423:                    if (n == 0) {
0424:                        n = getIndirectReferenceNumber();
0425:                        myXref.put(number, n);
0426:                    }
0427:                    return n;
0428:                } else
0429:                    return currentPdfReaderInstance.getNewObjectNumber(number,
0430:                            generation);
0431:            }
0432:
0433:            RandomAccessFileOrArray getReaderFile(PdfReader reader) {
0434:                if (readers2intrefs.containsKey(reader)) {
0435:                    RandomAccessFileOrArray raf = (RandomAccessFileOrArray) readers2file
0436:                            .get(reader);
0437:                    if (raf != null)
0438:                        return raf;
0439:                    return reader.getSafeFile();
0440:                }
0441:                if (currentPdfReaderInstance == null)
0442:                    return file;
0443:                else
0444:                    return currentPdfReaderInstance.getReaderFile();
0445:            }
0446:
0447:            /**
0448:             * @param reader
0449:             * @param openFile
0450:             * @throws IOException
0451:             */
0452:            public void registerReader(PdfReader reader, boolean openFile)
0453:                    throws IOException {
0454:                if (readers2intrefs.containsKey(reader))
0455:                    return;
0456:                readers2intrefs.put(reader, new IntHashtable());
0457:                if (openFile) {
0458:                    RandomAccessFileOrArray raf = reader.getSafeFile();
0459:                    readers2file.put(reader, raf);
0460:                    raf.reOpen();
0461:                }
0462:            }
0463:
0464:            /**
0465:             * @param reader
0466:             */
0467:            public void unRegisterReader(PdfReader reader) {
0468:                if (!readers2intrefs.containsKey(reader))
0469:                    return;
0470:                readers2intrefs.remove(reader);
0471:                RandomAccessFileOrArray raf = (RandomAccessFileOrArray) readers2file
0472:                        .get(reader);
0473:                if (raf == null)
0474:                    return;
0475:                readers2file.remove(reader);
0476:                try {
0477:                    raf.close();
0478:                } catch (Exception e) {
0479:                }
0480:            }
0481:
0482:            static void findAllObjects(PdfReader reader, PdfObject obj,
0483:                    IntHashtable hits) {
0484:                if (obj == null)
0485:                    return;
0486:                switch (obj.type()) {
0487:                case PdfObject.INDIRECT:
0488:                    PRIndirectReference iref = (PRIndirectReference) obj;
0489:                    if (reader != iref.getReader())
0490:                        return;
0491:                    if (hits.containsKey(iref.getNumber()))
0492:                        return;
0493:                    hits.put(iref.getNumber(), 1);
0494:                    findAllObjects(reader, PdfReader.getPdfObject(obj), hits);
0495:                    return;
0496:                case PdfObject.ARRAY:
0497:                    ArrayList lst = ((PdfArray) obj).getArrayList();
0498:                    for (int k = 0; k < lst.size(); ++k) {
0499:                        findAllObjects(reader, (PdfObject) lst.get(k), hits);
0500:                    }
0501:                    return;
0502:                case PdfObject.DICTIONARY:
0503:                case PdfObject.STREAM:
0504:                    PdfDictionary dic = (PdfDictionary) obj;
0505:                    for (Iterator it = dic.getKeys().iterator(); it.hasNext();) {
0506:                        PdfName name = (PdfName) it.next();
0507:                        findAllObjects(reader, dic.get(name), hits);
0508:                    }
0509:                    return;
0510:                }
0511:            }
0512:
0513:            /**
0514:             * @param fdf
0515:             * @throws IOException
0516:             */
0517:            public void addComments(FdfReader fdf) throws IOException {
0518:                if (readers2intrefs.containsKey(fdf))
0519:                    return;
0520:                PdfDictionary catalog = fdf.getCatalog();
0521:                catalog = (PdfDictionary) PdfReader.getPdfObject(catalog
0522:                        .get(PdfName.FDF));
0523:                if (catalog == null)
0524:                    return;
0525:                PdfArray annots = (PdfArray) PdfReader.getPdfObject(catalog
0526:                        .get(PdfName.ANNOTS));
0527:                if (annots == null || annots.size() == 0)
0528:                    return;
0529:                registerReader(fdf, false);
0530:                IntHashtable hits = new IntHashtable();
0531:                HashMap irt = new HashMap();
0532:                ArrayList an = new ArrayList();
0533:                ArrayList ar = annots.getArrayList();
0534:                for (int k = 0; k < ar.size(); ++k) {
0535:                    PdfObject obj = (PdfObject) ar.get(k);
0536:                    PdfDictionary annot = (PdfDictionary) PdfReader
0537:                            .getPdfObject(obj);
0538:                    PdfNumber page = (PdfNumber) PdfReader.getPdfObject(annot
0539:                            .get(PdfName.PAGE));
0540:                    if (page == null
0541:                            || page.intValue() >= reader.getNumberOfPages())
0542:                        continue;
0543:                    findAllObjects(fdf, obj, hits);
0544:                    an.add(obj);
0545:                    if (obj.type() == PdfObject.INDIRECT) {
0546:                        PdfObject nm = PdfReader.getPdfObject(annot
0547:                                .get(PdfName.NM));
0548:                        if (nm != null && nm.type() == PdfObject.STRING)
0549:                            irt.put(nm.toString(), obj);
0550:                    }
0551:                }
0552:                int arhits[] = hits.getKeys();
0553:                for (int k = 0; k < arhits.length; ++k) {
0554:                    int n = arhits[k];
0555:                    PdfObject obj = fdf.getPdfObject(n);
0556:                    if (obj.type() == PdfObject.DICTIONARY) {
0557:                        PdfObject str = PdfReader
0558:                                .getPdfObject(((PdfDictionary) obj)
0559:                                        .get(PdfName.IRT));
0560:                        if (str != null && str.type() == PdfObject.STRING) {
0561:                            PdfObject i = (PdfObject) irt.get(str.toString());
0562:                            if (i != null) {
0563:                                PdfDictionary dic2 = new PdfDictionary();
0564:                                dic2.merge((PdfDictionary) obj);
0565:                                dic2.put(PdfName.IRT, i);
0566:                                obj = dic2;
0567:                            }
0568:                        }
0569:                    }
0570:                    addToBody(obj, getNewObjectNumber(fdf, n, 0));
0571:                }
0572:                for (int k = 0; k < an.size(); ++k) {
0573:                    PdfObject obj = (PdfObject) an.get(k);
0574:                    PdfDictionary annot = (PdfDictionary) PdfReader
0575:                            .getPdfObject(obj);
0576:                    PdfNumber page = (PdfNumber) PdfReader.getPdfObject(annot
0577:                            .get(PdfName.PAGE));
0578:                    PdfDictionary dic = reader.getPageN(page.intValue() + 1);
0579:                    PdfArray annotsp = (PdfArray) PdfReader.getPdfObject(dic
0580:                            .get(PdfName.ANNOTS), dic);
0581:                    if (annotsp == null) {
0582:                        annotsp = new PdfArray();
0583:                        dic.put(PdfName.ANNOTS, annotsp);
0584:                        markUsed(dic);
0585:                    }
0586:                    markUsed(annotsp);
0587:                    annotsp.add(obj);
0588:                }
0589:            }
0590:
0591:            PageStamp getPageStamp(int pageNum) {
0592:                PdfDictionary pageN = reader.getPageN(pageNum);
0593:                PageStamp ps = (PageStamp) pagesToContent.get(pageN);
0594:                if (ps == null) {
0595:                    ps = new PageStamp(this , reader, pageN);
0596:                    pagesToContent.put(pageN, ps);
0597:                }
0598:                return ps;
0599:            }
0600:
0601:            PdfContentByte getUnderContent(int pageNum) {
0602:                if (pageNum < 1 || pageNum > reader.getNumberOfPages())
0603:                    return null;
0604:                PageStamp ps = getPageStamp(pageNum);
0605:                if (ps.under == null)
0606:                    ps.under = new StampContent(this , ps);
0607:                return ps.under;
0608:            }
0609:
0610:            PdfContentByte getOverContent(int pageNum) {
0611:                if (pageNum < 1 || pageNum > reader.getNumberOfPages())
0612:                    return null;
0613:                PageStamp ps = getPageStamp(pageNum);
0614:                if (ps.over == null)
0615:                    ps.over = new StampContent(this , ps);
0616:                return ps.over;
0617:            }
0618:
0619:            void correctAcroFieldPages(int page) {
0620:                if (acroFields == null)
0621:                    return;
0622:                if (page > reader.getNumberOfPages())
0623:                    return;
0624:                HashMap fields = acroFields.getFields();
0625:                for (Iterator it = fields.values().iterator(); it.hasNext();) {
0626:                    AcroFields.Item item = (AcroFields.Item) it.next();
0627:                    ArrayList pages = item.page;
0628:                    for (int k = 0; k < pages.size(); ++k) {
0629:                        int p = ((Integer) pages.get(k)).intValue();
0630:                        if (p >= page)
0631:                            pages.set(k, new Integer(p + 1));
0632:                    }
0633:                }
0634:            }
0635:
0636:            void insertPage(int pageNumber, Rectangle mediabox) {
0637:                Rectangle media = new Rectangle(mediabox);
0638:                int rotation = media.getRotation() % 360;
0639:                PdfDictionary page = new PdfDictionary(PdfName.PAGE);
0640:                PdfDictionary resources = new PdfDictionary();
0641:                PdfArray procset = new PdfArray();
0642:                procset.add(PdfName.PDF);
0643:                procset.add(PdfName.TEXT);
0644:                procset.add(PdfName.IMAGEB);
0645:                procset.add(PdfName.IMAGEC);
0646:                procset.add(PdfName.IMAGEI);
0647:                resources.put(PdfName.PROCSET, procset);
0648:                page.put(PdfName.RESOURCES, resources);
0649:                page.put(PdfName.ROTATE, new PdfNumber(rotation));
0650:                page.put(PdfName.MEDIABOX, new PdfRectangle(media, rotation));
0651:                PRIndirectReference pref = reader.addPdfObject(page);
0652:                PdfDictionary parent;
0653:                PRIndirectReference parentRef;
0654:                if (pageNumber > reader.getNumberOfPages()) {
0655:                    PdfDictionary lastPage = reader.getPageNRelease(reader
0656:                            .getNumberOfPages());
0657:                    parentRef = (PRIndirectReference) lastPage
0658:                            .get(PdfName.PARENT);
0659:                    parentRef = new PRIndirectReference(reader, parentRef
0660:                            .getNumber());
0661:                    parent = (PdfDictionary) PdfReader.getPdfObject(parentRef);
0662:                    PdfArray kids = (PdfArray) PdfReader.getPdfObject(parent
0663:                            .get(PdfName.KIDS), parent);
0664:                    kids.add(pref);
0665:                    markUsed(kids);
0666:                    reader.pageRefs.insertPage(pageNumber, pref);
0667:                } else {
0668:                    if (pageNumber < 1)
0669:                        pageNumber = 1;
0670:                    PdfDictionary firstPage = reader.getPageN(pageNumber);
0671:                    PRIndirectReference firstPageRef = reader
0672:                            .getPageOrigRef(pageNumber);
0673:                    reader.releasePage(pageNumber);
0674:                    parentRef = (PRIndirectReference) firstPage
0675:                            .get(PdfName.PARENT);
0676:                    parentRef = new PRIndirectReference(reader, parentRef
0677:                            .getNumber());
0678:                    parent = (PdfDictionary) PdfReader.getPdfObject(parentRef);
0679:                    PdfArray kids = (PdfArray) PdfReader.getPdfObject(parent
0680:                            .get(PdfName.KIDS), parent);
0681:                    ArrayList ar = kids.getArrayList();
0682:                    int len = ar.size();
0683:                    int num = firstPageRef.getNumber();
0684:                    for (int k = 0; k < len; ++k) {
0685:                        PRIndirectReference cur = (PRIndirectReference) ar
0686:                                .get(k);
0687:                        if (num == cur.getNumber()) {
0688:                            ar.add(k, pref);
0689:                            break;
0690:                        }
0691:                    }
0692:                    if (len == ar.size())
0693:                        throw new RuntimeException("Internal inconsistence.");
0694:                    markUsed(kids);
0695:                    reader.pageRefs.insertPage(pageNumber, pref);
0696:                    correctAcroFieldPages(pageNumber);
0697:                }
0698:                page.put(PdfName.PARENT, parentRef);
0699:                while (parent != null) {
0700:                    markUsed(parent);
0701:                    PdfNumber count = (PdfNumber) PdfReader
0702:                            .getPdfObjectRelease(parent.get(PdfName.COUNT));
0703:                    parent.put(PdfName.COUNT, new PdfNumber(
0704:                            count.intValue() + 1));
0705:                    parent = (PdfDictionary) PdfReader.getPdfObject(parent
0706:                            .get(PdfName.PARENT));
0707:                }
0708:            }
0709:
0710:            /** Getter for property rotateContents.
0711:             * @return Value of property rotateContents.
0712:             *
0713:             */
0714:            boolean isRotateContents() {
0715:                return this .rotateContents;
0716:            }
0717:
0718:            /** Setter for property rotateContents.
0719:             * @param rotateContents New value of property rotateContents.
0720:             *
0721:             */
0722:            void setRotateContents(boolean rotateContents) {
0723:                this .rotateContents = rotateContents;
0724:            }
0725:
0726:            boolean isContentWritten() {
0727:                return body.size() > 1;
0728:            }
0729:
0730:            AcroFields getAcroFields() {
0731:                if (acroFields == null) {
0732:                    acroFields = new AcroFields(reader, this );
0733:                }
0734:                return acroFields;
0735:            }
0736:
0737:            void setFormFlattening(boolean flat) {
0738:                this .flat = flat;
0739:            }
0740:
0741:            void setFreeTextFlattening(boolean flat) {
0742:                this .flatFreeText = flat;
0743:            }
0744:
0745:            boolean partialFormFlattening(String name) {
0746:                getAcroFields();
0747:                if (acroFields.getXfa().isXfaPresent())
0748:                    throw new UnsupportedOperationException(
0749:                            "Partial form flattening is not supported with XFA forms.");
0750:                if (!acroFields.getFields().containsKey(name))
0751:                    return false;
0752:                partialFlattening.add(name);
0753:                return true;
0754:            }
0755:
0756:            void flatFields() {
0757:                if (append)
0758:                    throw new IllegalArgumentException(
0759:                            "Field flattening is not supported in append mode.");
0760:                getAcroFields();
0761:                HashMap fields = acroFields.getFields();
0762:                if (fieldsAdded && partialFlattening.isEmpty()) {
0763:                    for (Iterator i = fields.keySet().iterator(); i.hasNext();) {
0764:                        partialFlattening.add(i.next());
0765:                    }
0766:                }
0767:                PdfDictionary acroForm = (PdfDictionary) PdfReader
0768:                        .getPdfObject(reader.getCatalog().get(PdfName.ACROFORM));
0769:                ArrayList acroFds = null;
0770:                if (acroForm != null) {
0771:                    PdfArray array = (PdfArray) PdfReader.getPdfObject(acroForm
0772:                            .get(PdfName.FIELDS), acroForm);
0773:                    if (array != null)
0774:                        acroFds = array.getArrayList();
0775:                }
0776:                for (Iterator i = fields.entrySet().iterator(); i.hasNext();) {
0777:                    Map.Entry entry = (Map.Entry) i.next();
0778:                    String name = (String) entry.getKey();
0779:                    if (!partialFlattening.isEmpty()
0780:                            && !partialFlattening.contains(name))
0781:                        continue;
0782:                    AcroFields.Item item = (AcroFields.Item) entry.getValue();
0783:                    for (int k = 0; k < item.merged.size(); ++k) {
0784:                        PdfDictionary merged = (PdfDictionary) item.merged
0785:                                .get(k);
0786:                        PdfNumber ff = (PdfNumber) PdfReader
0787:                                .getPdfObject(merged.get(PdfName.F));
0788:                        int flags = 0;
0789:                        if (ff != null)
0790:                            flags = ff.intValue();
0791:                        int page = ((Integer) item.page.get(k)).intValue();
0792:                        PdfDictionary appDic = (PdfDictionary) PdfReader
0793:                                .getPdfObject(merged.get(PdfName.AP));
0794:                        if (appDic != null
0795:                                && (flags & PdfFormField.FLAGS_PRINT) != 0
0796:                                && (flags & PdfFormField.FLAGS_HIDDEN) == 0) {
0797:                            PdfObject obj = appDic.get(PdfName.N);
0798:                            PdfAppearance app = null;
0799:                            if (obj != null) {
0800:                                PdfObject objReal = PdfReader.getPdfObject(obj);
0801:                                if (obj instanceof  PdfIndirectReference
0802:                                        && !obj.isIndirect())
0803:                                    app = new PdfAppearance(
0804:                                            (PdfIndirectReference) obj);
0805:                                else if (objReal instanceof  PdfStream) {
0806:                                    ((PdfDictionary) objReal).put(
0807:                                            PdfName.SUBTYPE, PdfName.FORM);
0808:                                    app = new PdfAppearance(
0809:                                            (PdfIndirectReference) obj);
0810:                                } else {
0811:                                    if (objReal != null
0812:                                            && objReal.isDictionary()) {
0813:                                        PdfName as = (PdfName) PdfReader
0814:                                                .getPdfObject(merged
0815:                                                        .get(PdfName.AS));
0816:                                        if (as != null) {
0817:                                            PdfIndirectReference iref = (PdfIndirectReference) ((PdfDictionary) objReal)
0818:                                                    .get(as);
0819:                                            if (iref != null) {
0820:                                                app = new PdfAppearance(iref);
0821:                                                if (iref.isIndirect()) {
0822:                                                    objReal = PdfReader
0823:                                                            .getPdfObject(iref);
0824:                                                    ((PdfDictionary) objReal)
0825:                                                            .put(
0826:                                                                    PdfName.SUBTYPE,
0827:                                                                    PdfName.FORM);
0828:                                                }
0829:                                            }
0830:                                        }
0831:                                    }
0832:                                }
0833:                            }
0834:                            if (app != null) {
0835:                                Rectangle box = PdfReader
0836:                                        .getNormalizedRectangle((PdfArray) PdfReader
0837:                                                .getPdfObject(merged
0838:                                                        .get(PdfName.RECT)));
0839:                                PdfContentByte cb = getOverContent(page);
0840:                                cb.setLiteral("Q ");
0841:                                cb.addTemplate(app, box.getLeft(), box
0842:                                        .getBottom());
0843:                                cb.setLiteral("q ");
0844:                            }
0845:                        }
0846:                        if (partialFlattening.isEmpty())
0847:                            continue;
0848:                        PdfDictionary pageDic = reader.getPageN(page);
0849:                        PdfArray annots = (PdfArray) PdfReader
0850:                                .getPdfObject(pageDic.get(PdfName.ANNOTS));
0851:                        if (annots == null)
0852:                            continue;
0853:                        ArrayList ar = annots.getArrayList();
0854:                        for (int idx = 0; idx < ar.size(); ++idx) {
0855:                            PdfObject ran = (PdfObject) ar.get(idx);
0856:                            if (!ran.isIndirect())
0857:                                continue;
0858:                            PdfObject ran2 = (PdfObject) item.widget_refs
0859:                                    .get(k);
0860:                            if (!ran2.isIndirect())
0861:                                continue;
0862:                            if (((PRIndirectReference) ran).getNumber() == ((PRIndirectReference) ran2)
0863:                                    .getNumber()) {
0864:                                ar.remove(idx--);
0865:                                PRIndirectReference wdref = (PRIndirectReference) ran2;
0866:                                while (true) {
0867:                                    PdfDictionary wd = (PdfDictionary) PdfReader
0868:                                            .getPdfObject(wdref);
0869:                                    PRIndirectReference parentRef = (PRIndirectReference) wd
0870:                                            .get(PdfName.PARENT);
0871:                                    PdfReader.killIndirect(wdref);
0872:                                    if (parentRef == null) { // reached AcroForm
0873:                                        for (int fr = 0; fr < acroFds.size(); ++fr) {
0874:                                            PdfObject h = (PdfObject) acroFds
0875:                                                    .get(fr);
0876:                                            if (h.isIndirect()
0877:                                                    && ((PRIndirectReference) h)
0878:                                                            .getNumber() == wdref
0879:                                                            .getNumber()) {
0880:                                                acroFds.remove(fr);
0881:                                                --fr;
0882:                                            }
0883:                                        }
0884:                                        break;
0885:                                    }
0886:                                    PdfDictionary parent = (PdfDictionary) PdfReader
0887:                                            .getPdfObject(parentRef);
0888:                                    PdfArray kids = (PdfArray) PdfReader
0889:                                            .getPdfObject(parent
0890:                                                    .get(PdfName.KIDS));
0891:                                    ArrayList kar = kids.getArrayList();
0892:                                    for (int fr = 0; fr < kar.size(); ++fr) {
0893:                                        PdfObject h = (PdfObject) kar.get(fr);
0894:                                        if (h.isIndirect()
0895:                                                && ((PRIndirectReference) h)
0896:                                                        .getNumber() == wdref
0897:                                                        .getNumber()) {
0898:                                            kar.remove(fr);
0899:                                            --fr;
0900:                                        }
0901:                                    }
0902:                                    if (!kar.isEmpty())
0903:                                        break;
0904:                                    wdref = parentRef;
0905:                                }
0906:                            }
0907:                        }
0908:                        if (ar.isEmpty()) {
0909:                            PdfReader.killIndirect(pageDic.get(PdfName.ANNOTS));
0910:                            pageDic.remove(PdfName.ANNOTS);
0911:                        }
0912:                    }
0913:                }
0914:                if (!fieldsAdded && partialFlattening.isEmpty()) {
0915:                    for (int page = 1; page <= reader.getNumberOfPages(); ++page) {
0916:                        PdfDictionary pageDic = reader.getPageN(page);
0917:                        PdfArray annots = (PdfArray) PdfReader
0918:                                .getPdfObject(pageDic.get(PdfName.ANNOTS));
0919:                        if (annots == null)
0920:                            continue;
0921:                        ArrayList ar = annots.getArrayList();
0922:                        for (int idx = 0; idx < ar.size(); ++idx) {
0923:                            PdfObject annoto = PdfReader
0924:                                    .getPdfObject((PdfObject) ar.get(idx));
0925:                            if ((annoto instanceof  PdfIndirectReference)
0926:                                    && !annoto.isIndirect())
0927:                                continue;
0928:                            if (!annoto.isDictionary()
0929:                                    || PdfName.WIDGET
0930:                                            .equals(((PdfDictionary) annoto)
0931:                                                    .get(PdfName.SUBTYPE))) {
0932:                                ar.remove(idx);
0933:                                --idx;
0934:                            }
0935:                        }
0936:                        if (ar.isEmpty()) {
0937:                            PdfReader.killIndirect(pageDic.get(PdfName.ANNOTS));
0938:                            pageDic.remove(PdfName.ANNOTS);
0939:                        }
0940:                    }
0941:                    eliminateAcroformObjects();
0942:                }
0943:            }
0944:
0945:            void eliminateAcroformObjects() {
0946:                PdfObject acro = reader.getCatalog().get(PdfName.ACROFORM);
0947:                if (acro == null)
0948:                    return;
0949:                PdfDictionary acrodic = (PdfDictionary) PdfReader
0950:                        .getPdfObject(acro);
0951:                reader.killXref(acrodic.get(PdfName.XFA));
0952:                acrodic.remove(PdfName.XFA);
0953:                PdfObject iFields = acrodic.get(PdfName.FIELDS);
0954:                if (iFields != null) {
0955:                    PdfDictionary kids = new PdfDictionary();
0956:                    kids.put(PdfName.KIDS, iFields);
0957:                    sweepKids(kids);
0958:                    PdfReader.killIndirect(iFields);
0959:                    acrodic.put(PdfName.FIELDS, new PdfArray());
0960:                }
0961:                //        PdfReader.killIndirect(acro);
0962:                //        reader.getCatalog().remove(PdfName.ACROFORM);
0963:            }
0964:
0965:            void sweepKids(PdfObject obj) {
0966:                PdfObject oo = PdfReader.killIndirect(obj);
0967:                if (oo == null || !oo.isDictionary())
0968:                    return;
0969:                PdfDictionary dic = (PdfDictionary) oo;
0970:                PdfArray kids = (PdfArray) PdfReader.killIndirect(dic
0971:                        .get(PdfName.KIDS));
0972:                if (kids == null)
0973:                    return;
0974:                ArrayList ar = kids.getArrayList();
0975:                for (int k = 0; k < ar.size(); ++k) {
0976:                    sweepKids((PdfObject) ar.get(k));
0977:                }
0978:            }
0979:
0980:            private void flatFreeTextFields() {
0981:                if (append)
0982:                    throw new IllegalArgumentException(
0983:                            "FreeText flattening is not supported in append mode.");
0984:
0985:                for (int page = 1; page <= reader.getNumberOfPages(); ++page) {
0986:                    PdfDictionary pageDic = reader.getPageN(page);
0987:                    PdfArray annots = (PdfArray) PdfReader.getPdfObject(pageDic
0988:                            .get(PdfName.ANNOTS));
0989:                    if (annots == null)
0990:                        continue;
0991:                    ArrayList ar = annots.getArrayList();
0992:                    for (int idx = 0; idx < ar.size(); ++idx) {
0993:                        PdfObject annoto = PdfReader
0994:                                .getPdfObject((PdfObject) ar.get(idx));
0995:                        if ((annoto instanceof  PdfIndirectReference)
0996:                                && !annoto.isIndirect())
0997:                            continue;
0998:
0999:                        PdfDictionary annDic = (PdfDictionary) annoto;
1000:                        if (!((PdfName) annDic.get(PdfName.SUBTYPE))
1001:                                .equals(PdfName.FREETEXT))
1002:                            continue;
1003:                        PdfNumber ff = (PdfNumber) PdfReader
1004:                                .getPdfObject(annDic.get(PdfName.F));
1005:                        int flags = (ff != null) ? ff.intValue() : 0;
1006:
1007:                        if ((flags & PdfFormField.FLAGS_PRINT) != 0
1008:                                && (flags & PdfFormField.FLAGS_HIDDEN) == 0) {
1009:                            PdfObject obj1 = annDic.get(PdfName.AP);
1010:                            if (obj1 == null)
1011:                                continue;
1012:                            PdfDictionary appDic = (obj1 instanceof  PdfIndirectReference) ? (PdfDictionary) PdfReader
1013:                                    .getPdfObject(obj1)
1014:                                    : (PdfDictionary) obj1;
1015:                            PdfObject obj = appDic.get(PdfName.N);
1016:                            PdfAppearance app = null;
1017:                            PdfObject objReal = PdfReader.getPdfObject(obj);
1018:
1019:                            if (obj instanceof  PdfIndirectReference
1020:                                    && !obj.isIndirect())
1021:                                app = new PdfAppearance(
1022:                                        (PdfIndirectReference) obj);
1023:                            else if (objReal instanceof  PdfStream) {
1024:                                ((PdfDictionary) objReal).put(PdfName.SUBTYPE,
1025:                                        PdfName.FORM);
1026:                                app = new PdfAppearance(
1027:                                        (PdfIndirectReference) obj);
1028:                            } else {
1029:                                if (objReal.isDictionary()) {
1030:                                    PdfName as_p = (PdfName) PdfReader
1031:                                            .getPdfObject(appDic
1032:                                                    .get(PdfName.AS));
1033:                                    if (as_p != null) {
1034:                                        PdfIndirectReference iref = (PdfIndirectReference) ((PdfDictionary) objReal)
1035:                                                .get(as_p);
1036:                                        if (iref != null) {
1037:                                            app = new PdfAppearance(iref);
1038:                                            if (iref.isIndirect()) {
1039:                                                objReal = PdfReader
1040:                                                        .getPdfObject(iref);
1041:                                                ((PdfDictionary) objReal).put(
1042:                                                        PdfName.SUBTYPE,
1043:                                                        PdfName.FORM);
1044:                                            }
1045:                                        }
1046:                                    }
1047:                                }
1048:                            }
1049:                            if (app != null) {
1050:                                Rectangle box = PdfReader
1051:                                        .getNormalizedRectangle((PdfArray) PdfReader
1052:                                                .getPdfObject(annDic
1053:                                                        .get(PdfName.RECT)));
1054:                                PdfContentByte cb = getOverContent(page);
1055:                                cb.setLiteral("Q ");
1056:                                cb.addTemplate(app, box.getLeft(), box
1057:                                        .getBottom());
1058:                                cb.setLiteral("q ");
1059:                            }
1060:                        }
1061:                    }
1062:                    for (int idx = 0; idx < ar.size(); ++idx) {
1063:                        PdfObject annoto = PdfReader
1064:                                .getPdfObject((PdfObject) ar.get(idx));
1065:                        if (annoto != null && annoto.isDictionary()) {
1066:                            PdfDictionary annot = (PdfDictionary) annoto;
1067:                            if (PdfName.FREETEXT.equals(annot
1068:                                    .get(PdfName.SUBTYPE))) {
1069:                                ar.remove(idx);
1070:                                --idx;
1071:                            }
1072:                        }
1073:                    }
1074:                    if (ar.isEmpty()) {
1075:                        PdfReader.killIndirect(pageDic.get(PdfName.ANNOTS));
1076:                        pageDic.remove(PdfName.ANNOTS);
1077:                    }
1078:                }
1079:            }
1080:
1081:            /**
1082:             * @see com.lowagie.text.pdf.PdfWriter#getPageReference(int)
1083:             */
1084:            public PdfIndirectReference getPageReference(int page) {
1085:                PdfIndirectReference ref = reader.getPageOrigRef(page);
1086:                if (ref == null)
1087:                    throw new IllegalArgumentException("Invalid page number "
1088:                            + page);
1089:                return ref;
1090:            }
1091:
1092:            /**
1093:             * @see com.lowagie.text.pdf.PdfWriter#addAnnotation(com.lowagie.text.pdf.PdfAnnotation)
1094:             */
1095:            public void addAnnotation(PdfAnnotation annot) {
1096:                throw new RuntimeException(
1097:                        "Unsupported in this context. Use PdfStamper.addAnnotation()");
1098:            }
1099:
1100:            void addDocumentField(PdfIndirectReference ref) {
1101:                PdfDictionary catalog = reader.getCatalog();
1102:                PdfDictionary acroForm = (PdfDictionary) PdfReader
1103:                        .getPdfObject(catalog.get(PdfName.ACROFORM), catalog);
1104:                if (acroForm == null) {
1105:                    acroForm = new PdfDictionary();
1106:                    catalog.put(PdfName.ACROFORM, acroForm);
1107:                    markUsed(catalog);
1108:                }
1109:                PdfArray fields = (PdfArray) PdfReader.getPdfObject(acroForm
1110:                        .get(PdfName.FIELDS), acroForm);
1111:                if (fields == null) {
1112:                    fields = new PdfArray();
1113:                    acroForm.put(PdfName.FIELDS, fields);
1114:                    markUsed(acroForm);
1115:                }
1116:                if (!acroForm.contains(PdfName.DA)) {
1117:                    acroForm.put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g "));
1118:                    markUsed(acroForm);
1119:                }
1120:                fields.add(ref);
1121:                markUsed(fields);
1122:            }
1123:
1124:            void addFieldResources() throws IOException {
1125:                if (fieldTemplates.isEmpty())
1126:                    return;
1127:                PdfDictionary catalog = reader.getCatalog();
1128:                PdfDictionary acroForm = (PdfDictionary) PdfReader
1129:                        .getPdfObject(catalog.get(PdfName.ACROFORM), catalog);
1130:                if (acroForm == null) {
1131:                    acroForm = new PdfDictionary();
1132:                    catalog.put(PdfName.ACROFORM, acroForm);
1133:                    markUsed(catalog);
1134:                }
1135:                PdfDictionary dr = (PdfDictionary) PdfReader.getPdfObject(
1136:                        acroForm.get(PdfName.DR), acroForm);
1137:                if (dr == null) {
1138:                    dr = new PdfDictionary();
1139:                    acroForm.put(PdfName.DR, dr);
1140:                    markUsed(acroForm);
1141:                }
1142:                markUsed(dr);
1143:                for (Iterator it = fieldTemplates.keySet().iterator(); it
1144:                        .hasNext();) {
1145:                    PdfTemplate template = (PdfTemplate) it.next();
1146:                    PdfFormField.mergeResources(dr, (PdfDictionary) template
1147:                            .getResources(), this );
1148:                }
1149:                if (dr.get(PdfName.ENCODING) == null)
1150:                    dr.put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING);
1151:                PdfDictionary fonts = (PdfDictionary) PdfReader.getPdfObject(dr
1152:                        .get(PdfName.FONT));
1153:                if (fonts == null) {
1154:                    fonts = new PdfDictionary();
1155:                    dr.put(PdfName.FONT, fonts);
1156:                }
1157:                if (!fonts.contains(PdfName.HELV)) {
1158:                    PdfDictionary dic = new PdfDictionary(PdfName.FONT);
1159:                    dic.put(PdfName.BASEFONT, PdfName.HELVETICA);
1160:                    dic.put(PdfName.ENCODING, PdfName.WIN_ANSI_ENCODING);
1161:                    dic.put(PdfName.NAME, PdfName.HELV);
1162:                    dic.put(PdfName.SUBTYPE, PdfName.TYPE1);
1163:                    fonts.put(PdfName.HELV, addToBody(dic)
1164:                            .getIndirectReference());
1165:                }
1166:                if (!fonts.contains(PdfName.ZADB)) {
1167:                    PdfDictionary dic = new PdfDictionary(PdfName.FONT);
1168:                    dic.put(PdfName.BASEFONT, PdfName.ZAPFDINGBATS);
1169:                    dic.put(PdfName.NAME, PdfName.ZADB);
1170:                    dic.put(PdfName.SUBTYPE, PdfName.TYPE1);
1171:                    fonts.put(PdfName.ZADB, addToBody(dic)
1172:                            .getIndirectReference());
1173:                }
1174:                if (acroForm.get(PdfName.DA) == null) {
1175:                    acroForm.put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g "));
1176:                    markUsed(acroForm);
1177:                }
1178:            }
1179:
1180:            void expandFields(PdfFormField field, ArrayList allAnnots) {
1181:                allAnnots.add(field);
1182:                ArrayList kids = field.getKids();
1183:                if (kids != null) {
1184:                    for (int k = 0; k < kids.size(); ++k)
1185:                        expandFields((PdfFormField) kids.get(k), allAnnots);
1186:                }
1187:            }
1188:
1189:            void addAnnotation(PdfAnnotation annot, PdfDictionary pageN) {
1190:                try {
1191:                    ArrayList allAnnots = new ArrayList();
1192:                    if (annot.isForm()) {
1193:                        fieldsAdded = true;
1194:                        getAcroFields();
1195:                        PdfFormField field = (PdfFormField) annot;
1196:                        if (field.getParent() != null)
1197:                            return;
1198:                        expandFields(field, allAnnots);
1199:                    } else
1200:                        allAnnots.add(annot);
1201:                    for (int k = 0; k < allAnnots.size(); ++k) {
1202:                        annot = (PdfAnnotation) allAnnots.get(k);
1203:                        if (annot.getPlaceInPage() > 0)
1204:                            pageN = reader.getPageN(annot.getPlaceInPage());
1205:                        if (annot.isForm()) {
1206:                            if (!annot.isUsed()) {
1207:                                HashMap templates = annot.getTemplates();
1208:                                if (templates != null)
1209:                                    fieldTemplates.putAll(templates);
1210:                            }
1211:                            PdfFormField field = (PdfFormField) annot;
1212:                            if (field.getParent() == null)
1213:                                addDocumentField(field.getIndirectReference());
1214:                        }
1215:                        if (annot.isAnnotation()) {
1216:                            PdfObject pdfobj = PdfReader.getPdfObject(pageN
1217:                                    .get(PdfName.ANNOTS), pageN);
1218:                            PdfArray annots = null;
1219:                            if (pdfobj == null || !pdfobj.isArray()) {
1220:                                annots = new PdfArray();
1221:                                pageN.put(PdfName.ANNOTS, annots);
1222:                                markUsed(pageN);
1223:                            } else
1224:                                annots = (PdfArray) pdfobj;
1225:                            annots.add(annot.getIndirectReference());
1226:                            markUsed(annots);
1227:                            if (!annot.isUsed()) {
1228:                                PdfRectangle rect = (PdfRectangle) annot
1229:                                        .get(PdfName.RECT);
1230:                                if (rect != null
1231:                                        && (rect.left() != 0
1232:                                                || rect.right() != 0
1233:                                                || rect.top() != 0 || rect
1234:                                                .bottom() != 0)) {
1235:                                    int rotation = reader
1236:                                            .getPageRotation(pageN);
1237:                                    Rectangle pageSize = reader
1238:                                            .getPageSizeWithRotation(pageN);
1239:                                    switch (rotation) {
1240:                                    case 90:
1241:                                        annot.put(PdfName.RECT,
1242:                                                new PdfRectangle(pageSize
1243:                                                        .getTop()
1244:                                                        - rect.bottom(), rect
1245:                                                        .left(), pageSize
1246:                                                        .getTop()
1247:                                                        - rect.top(), rect
1248:                                                        .right()));
1249:                                        break;
1250:                                    case 180:
1251:                                        annot.put(PdfName.RECT,
1252:                                                new PdfRectangle(pageSize
1253:                                                        .getRight()
1254:                                                        - rect.left(), pageSize
1255:                                                        .getTop()
1256:                                                        - rect.bottom(),
1257:                                                        pageSize.getRight()
1258:                                                                - rect.right(),
1259:                                                        pageSize.getTop()
1260:                                                                - rect.top()));
1261:                                        break;
1262:                                    case 270:
1263:                                        annot
1264:                                                .put(
1265:                                                        PdfName.RECT,
1266:                                                        new PdfRectangle(
1267:                                                                rect.bottom(),
1268:                                                                pageSize
1269:                                                                        .getRight()
1270:                                                                        - rect
1271:                                                                                .left(),
1272:                                                                rect.top(),
1273:                                                                pageSize
1274:                                                                        .getRight()
1275:                                                                        - rect
1276:                                                                                .right()));
1277:                                        break;
1278:                                    }
1279:                                }
1280:                            }
1281:                        }
1282:                        if (!annot.isUsed()) {
1283:                            annot.setUsed();
1284:                            addToBody(annot, annot.getIndirectReference());
1285:                        }
1286:                    }
1287:                } catch (IOException e) {
1288:                    throw new ExceptionConverter(e);
1289:                }
1290:            }
1291:
1292:            void addAnnotation(PdfAnnotation annot, int page) {
1293:                addAnnotation(annot, reader.getPageN(page));
1294:            }
1295:
1296:            private void outlineTravel(PRIndirectReference outline) {
1297:                while (outline != null) {
1298:                    PdfDictionary outlineR = (PdfDictionary) PdfReader
1299:                            .getPdfObjectRelease(outline);
1300:                    PRIndirectReference first = (PRIndirectReference) outlineR
1301:                            .get(PdfName.FIRST);
1302:                    if (first != null) {
1303:                        outlineTravel(first);
1304:                    }
1305:                    PdfReader.killIndirect(outlineR.get(PdfName.DEST));
1306:                    PdfReader.killIndirect(outlineR.get(PdfName.A));
1307:                    PdfReader.killIndirect(outline);
1308:                    outline = (PRIndirectReference) outlineR.get(PdfName.NEXT);
1309:                }
1310:            }
1311:
1312:            void deleteOutlines() {
1313:                PdfDictionary catalog = reader.getCatalog();
1314:                PRIndirectReference outlines = (PRIndirectReference) catalog
1315:                        .get(PdfName.OUTLINES);
1316:                if (outlines == null)
1317:                    return;
1318:                outlineTravel(outlines);
1319:                PdfReader.killIndirect(outlines);
1320:                catalog.remove(PdfName.OUTLINES);
1321:                markUsed(catalog);
1322:            }
1323:
1324:            void setJavaScript() throws IOException {
1325:                HashMap djs = pdf.getDocumentLevelJS();
1326:                if (djs.isEmpty())
1327:                    return;
1328:                PdfDictionary catalog = reader.getCatalog();
1329:                PdfDictionary names = (PdfDictionary) PdfReader.getPdfObject(
1330:                        catalog.get(PdfName.NAMES), catalog);
1331:                if (names == null) {
1332:                    names = new PdfDictionary();
1333:                    catalog.put(PdfName.NAMES, names);
1334:                    markUsed(catalog);
1335:                }
1336:                markUsed(names);
1337:                PdfDictionary tree = PdfNameTree.writeTree(djs, this );
1338:                names.put(PdfName.JAVASCRIPT, addToBody(tree)
1339:                        .getIndirectReference());
1340:            }
1341:
1342:            void addFileAttachments() throws IOException {
1343:                HashMap fs = pdf.getDocumentFileAttachment();
1344:                if (fs.isEmpty())
1345:                    return;
1346:                PdfDictionary catalog = reader.getCatalog();
1347:                PdfDictionary names = (PdfDictionary) PdfReader.getPdfObject(
1348:                        catalog.get(PdfName.NAMES), catalog);
1349:                if (names == null) {
1350:                    names = new PdfDictionary();
1351:                    catalog.put(PdfName.NAMES, names);
1352:                    markUsed(catalog);
1353:                }
1354:                markUsed(names);
1355:                HashMap old = PdfNameTree.readTree((PdfDictionary) PdfReader
1356:                        .getPdfObjectRelease(names.get(PdfName.EMBEDDEDFILES)));
1357:                for (Iterator it = fs.entrySet().iterator(); it.hasNext();) {
1358:                    Map.Entry entry = (Map.Entry) it.next();
1359:                    String name = (String) entry.getKey();
1360:                    int k = 0;
1361:                    String nn = name;
1362:                    while (old.containsKey(nn)) {
1363:                        ++k;
1364:                        nn += " " + k;
1365:                    }
1366:                    old.put(nn, entry.getValue());
1367:                }
1368:                PdfDictionary tree = PdfNameTree.writeTree(old, this );
1369:                names.put(PdfName.EMBEDDEDFILES, addToBody(tree)
1370:                        .getIndirectReference());
1371:            }
1372:
1373:            /**
1374:             * Adds or replaces the Collection Dictionary in the Catalog.
1375:             * @param	collection	the new collection dictionary.
1376:             */
1377:            void makePackage(PdfCollection collection) {
1378:                PdfDictionary catalog = reader.getCatalog();
1379:                catalog.put(PdfName.COLLECTION, collection);
1380:            }
1381:
1382:            void setOutlines() throws IOException {
1383:                if (newBookmarks == null)
1384:                    return;
1385:                deleteOutlines();
1386:                if (newBookmarks.isEmpty())
1387:                    return;
1388:                PdfDictionary catalog = reader.getCatalog();
1389:                boolean namedAsNames = (catalog.get(PdfName.DESTS) != null);
1390:                writeOutlines(catalog, namedAsNames);
1391:                markUsed(catalog);
1392:            }
1393:
1394:            /**
1395:             * Sets the viewer preferences.
1396:             * @param preferences the viewer preferences
1397:             * @see PdfWriter#setViewerPreferences(int)
1398:             */
1399:            public void setViewerPreferences(int preferences) {
1400:                useVp = true;
1401:                this .viewerPreferences.setViewerPreferences(preferences);
1402:            }
1403:
1404:            /** Adds a viewer preference
1405:             * @param key a key for a viewer preference
1406:             * @param value the value for the viewer preference
1407:             * @see PdfViewerPreferences#addViewerPreference
1408:             */
1409:            public void addViewerPreference(PdfName key, PdfObject value) {
1410:                useVp = true;
1411:                this .viewerPreferences.addViewerPreference(key, value);
1412:            }
1413:
1414:            /**
1415:             * Set the signature flags.
1416:             * @param f the flags. This flags are ORed with current ones
1417:             */
1418:            public void setSigFlags(int f) {
1419:                sigFlags |= f;
1420:            }
1421:
1422:            /** Always throws an <code>UnsupportedOperationException</code>.
1423:             * @param actionType ignore
1424:             * @param action ignore
1425:             * @throws PdfException ignore
1426:             * @see PdfStamper#setPageAction(PdfName, PdfAction, int)
1427:             */
1428:            public void setPageAction(PdfName actionType, PdfAction action)
1429:                    throws PdfException {
1430:                throw new UnsupportedOperationException(
1431:                        "Use setPageAction(PdfName actionType, PdfAction action, int page)");
1432:            }
1433:
1434:            /**
1435:             * Sets the open and close page additional action.
1436:             * @param actionType the action type. It can be <CODE>PdfWriter.PAGE_OPEN</CODE>
1437:             * or <CODE>PdfWriter.PAGE_CLOSE</CODE>
1438:             * @param action the action to perform
1439:             * @param page the page where the action will be applied. The first page is 1
1440:             * @throws PdfException if the action type is invalid
1441:             */
1442:            void setPageAction(PdfName actionType, PdfAction action, int page)
1443:                    throws PdfException {
1444:                if (!actionType.equals(PAGE_OPEN)
1445:                        && !actionType.equals(PAGE_CLOSE))
1446:                    throw new PdfException(
1447:                            "Invalid page additional action type: "
1448:                                    + actionType.toString());
1449:                PdfDictionary pg = reader.getPageN(page);
1450:                PdfDictionary aa = (PdfDictionary) PdfReader.getPdfObject(pg
1451:                        .get(PdfName.AA), pg);
1452:                if (aa == null) {
1453:                    aa = new PdfDictionary();
1454:                    pg.put(PdfName.AA, aa);
1455:                    markUsed(pg);
1456:                }
1457:                aa.put(actionType, action);
1458:                markUsed(aa);
1459:            }
1460:
1461:            /**
1462:             * Always throws an <code>UnsupportedOperationException</code>.
1463:             * @param seconds ignore
1464:             */
1465:            public void setDuration(int seconds) {
1466:                throw new UnsupportedOperationException(
1467:                        "Use setPageAction(PdfName actionType, PdfAction action, int page)");
1468:            }
1469:
1470:            /**
1471:             * Always throws an <code>UnsupportedOperationException</code>.
1472:             * @param transition ignore
1473:             */
1474:            public void setTransition(PdfTransition transition) {
1475:                throw new UnsupportedOperationException(
1476:                        "Use setPageAction(PdfName actionType, PdfAction action, int page)");
1477:            }
1478:
1479:            /**
1480:             * Sets the display duration for the page (for presentations)
1481:             * @param seconds   the number of seconds to display the page. A negative value removes the entry
1482:             * @param page the page where the duration will be applied. The first page is 1
1483:             */
1484:            void setDuration(int seconds, int page) {
1485:                PdfDictionary pg = reader.getPageN(page);
1486:                if (seconds < 0)
1487:                    pg.remove(PdfName.DUR);
1488:                else
1489:                    pg.put(PdfName.DUR, new PdfNumber(seconds));
1490:                markUsed(pg);
1491:            }
1492:
1493:            /**
1494:             * Sets the transition for the page
1495:             * @param transition   the transition object. A <code>null</code> removes the transition
1496:             * @param page the page where the transition will be applied. The first page is 1
1497:             */
1498:            void setTransition(PdfTransition transition, int page) {
1499:                PdfDictionary pg = reader.getPageN(page);
1500:                if (transition == null)
1501:                    pg.remove(PdfName.TRANS);
1502:                else
1503:                    pg.put(PdfName.TRANS, transition.getTransitionDictionary());
1504:                markUsed(pg);
1505:            }
1506:
1507:            protected void markUsed(PdfObject obj) {
1508:                if (append && obj != null) {
1509:                    PRIndirectReference ref = null;
1510:                    if (obj.type() == PdfObject.INDIRECT)
1511:                        ref = (PRIndirectReference) obj;
1512:                    else
1513:                        ref = obj.getIndRef();
1514:                    if (ref != null)
1515:                        marked.put(ref.getNumber(), 1);
1516:                }
1517:            }
1518:
1519:            protected void markUsed(int num) {
1520:                if (append)
1521:                    marked.put(num, 1);
1522:            }
1523:
1524:            /**
1525:             * Getter for property append.
1526:             * @return Value of property append.
1527:             */
1528:            boolean isAppend() {
1529:                return append;
1530:            }
1531:
1532:            /** Additional-actions defining the actions to be taken in
1533:             * response to various trigger events affecting the document
1534:             * as a whole. The actions types allowed are: <CODE>DOCUMENT_CLOSE</CODE>,
1535:             * <CODE>WILL_SAVE</CODE>, <CODE>DID_SAVE</CODE>, <CODE>WILL_PRINT</CODE>
1536:             * and <CODE>DID_PRINT</CODE>.
1537:             *
1538:             * @param actionType the action type
1539:             * @param action the action to execute in response to the trigger
1540:             * @throws PdfException on invalid action type
1541:             */
1542:            public void setAdditionalAction(PdfName actionType, PdfAction action)
1543:                    throws PdfException {
1544:                if (!(actionType.equals(DOCUMENT_CLOSE)
1545:                        || actionType.equals(WILL_SAVE)
1546:                        || actionType.equals(DID_SAVE)
1547:                        || actionType.equals(WILL_PRINT) || actionType
1548:                        .equals(DID_PRINT))) {
1549:                    throw new PdfException("Invalid additional action type: "
1550:                            + actionType.toString());
1551:                }
1552:                PdfDictionary aa = (PdfDictionary) PdfReader
1553:                        .getPdfObject(reader.getCatalog().get(PdfName.AA));
1554:                if (aa == null) {
1555:                    if (action == null)
1556:                        return;
1557:                    aa = new PdfDictionary();
1558:                    reader.getCatalog().put(PdfName.AA, aa);
1559:                }
1560:                markUsed(aa);
1561:                if (action == null)
1562:                    aa.remove(actionType);
1563:                else
1564:                    aa.put(actionType, action);
1565:            }
1566:
1567:            /**
1568:             * @see com.lowagie.text.pdf.PdfWriter#setOpenAction(com.lowagie.text.pdf.PdfAction)
1569:             */
1570:            public void setOpenAction(PdfAction action) {
1571:                openAction = action;
1572:            }
1573:
1574:            /**
1575:             * @see com.lowagie.text.pdf.PdfWriter#setOpenAction(java.lang.String)
1576:             */
1577:            public void setOpenAction(String name) {
1578:                throw new UnsupportedOperationException(
1579:                        "Open actions by name are not supported.");
1580:            }
1581:
1582:            /**
1583:             * @see com.lowagie.text.pdf.PdfWriter#setThumbnail(com.lowagie.text.Image)
1584:             */
1585:            public void setThumbnail(com.lowagie.text.Image image) {
1586:                throw new UnsupportedOperationException(
1587:                        "Use PdfStamper.setThumbnail().");
1588:            }
1589:
1590:            void setThumbnail(Image image, int page) throws PdfException,
1591:                    DocumentException {
1592:                PdfIndirectReference thumb = getImageReference(addDirectImageSimple(image));
1593:                reader.resetReleasePage();
1594:                PdfDictionary dic = reader.getPageN(page);
1595:                dic.put(PdfName.THUMB, thumb);
1596:                reader.resetReleasePage();
1597:            }
1598:
1599:            public PdfContentByte getDirectContentUnder() {
1600:                throw new UnsupportedOperationException(
1601:                        "Use PdfStamper.getUnderContent() or PdfStamper.getOverContent()");
1602:            }
1603:
1604:            public PdfContentByte getDirectContent() {
1605:                throw new UnsupportedOperationException(
1606:                        "Use PdfStamper.getUnderContent() or PdfStamper.getOverContent()");
1607:            }
1608:
1609:            static class PageStamp {
1610:
1611:                PdfDictionary pageN;
1612:                StampContent under;
1613:                StampContent over;
1614:                PageResources pageResources;
1615:
1616:                PageStamp(PdfStamperImp stamper, PdfReader reader,
1617:                        PdfDictionary pageN) {
1618:                    this .pageN = pageN;
1619:                    pageResources = new PageResources();
1620:                    PdfDictionary resources = (PdfDictionary) PdfReader
1621:                            .getPdfObject(pageN.get(PdfName.RESOURCES));
1622:                    pageResources.setOriginalResources(resources,
1623:                            stamper.namePtr);
1624:                }
1625:            }
1626:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.