新疆交投路损赔补偿系统 v1.0.2版本的 MD5 值为:5e336668c8c96e65d739f00d1fa2a3b9

以下内容为反编译后的 PdfWriter.java 源代码,内容仅作参考


package com.itextpdf.text.pdf;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocListener;
import com.itextpdf.text.DocWriter;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.ExceptionConverter;
import com.itextpdf.text.Image;
import com.itextpdf.text.ImgJBIG2;
import com.itextpdf.text.ImgWMF;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.Version;
import com.itextpdf.text.error_messages.MessageLocalization;
import com.itextpdf.text.html.HtmlTags;
import com.itextpdf.text.log.Counter;
import com.itextpdf.text.log.CounterFactory;
import com.itextpdf.text.pdf.PdfDocument;
import com.itextpdf.text.pdf.collection.PdfCollection;
import com.itextpdf.text.pdf.events.PdfPageEventForwarder;
import com.itextpdf.text.pdf.interfaces.IAccessibleElement;
import com.itextpdf.text.pdf.interfaces.PdfAnnotations;
import com.itextpdf.text.pdf.interfaces.PdfDocumentActions;
import com.itextpdf.text.pdf.interfaces.PdfEncryptionSettings;
import com.itextpdf.text.pdf.interfaces.PdfIsoConformance;
import com.itextpdf.text.pdf.interfaces.PdfPageActions;
import com.itextpdf.text.pdf.interfaces.PdfRunDirection;
import com.itextpdf.text.pdf.interfaces.PdfVersion;
import com.itextpdf.text.pdf.interfaces.PdfViewerPreferences;
import com.itextpdf.text.pdf.interfaces.PdfXConformance;
import com.itextpdf.text.pdf.internal.PdfVersionImp;
import com.itextpdf.text.pdf.internal.PdfXConformanceImp;
import com.itextpdf.text.xml.xmp.PdfProperties;
import com.itextpdf.text.xml.xmp.XmpWriter;
import com.itextpdf.xmp.XMPConst;
import com.itextpdf.xmp.XMPException;
import com.itextpdf.xmp.options.PropertyOptions;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
public class PdfWriter extends DocWriter implements PdfViewerPreferences, PdfEncryptionSettings, PdfVersion, PdfDocumentActions, PdfPageActions, PdfRunDirection, PdfAnnotations {
    public static final int ALLOW_ASSEMBLY = 1024;
    public static final int ALLOW_COPY = 16;
    public static final int ALLOW_DEGRADED_PRINTING = 4;
    public static final int ALLOW_FILL_IN = 256;
    public static final int ALLOW_MODIFY_ANNOTATIONS = 32;
    public static final int ALLOW_MODIFY_CONTENTS = 8;
    public static final int ALLOW_PRINTING = 2052;
    public static final int ALLOW_SCREENREADERS = 512;
    @Deprecated
    public static final int AllowAssembly = 1024;
    @Deprecated
    public static final int AllowCopy = 16;
    @Deprecated
    public static final int AllowDegradedPrinting = 4;
    @Deprecated
    public static final int AllowFillIn = 256;
    @Deprecated
    public static final int AllowModifyAnnotations = 32;
    @Deprecated
    public static final int AllowModifyContents = 8;
    @Deprecated
    public static final int AllowPrinting = 2052;
    @Deprecated
    public static final int AllowScreenReaders = 512;
    public static final int CenterWindow = 65536;
    public static final int DO_NOT_ENCRYPT_METADATA = 8;
    public static final int DirectionL2R = 4194304;
    public static final int DirectionR2L = 8388608;
    public static final int DisplayDocTitle = 131072;
    public static final int EMBEDDED_FILES_ONLY = 24;
    public static final int ENCRYPTION_AES_128 = 2;
    public static final int ENCRYPTION_AES_256 = 3;
    static final int ENCRYPTION_MASK = 7;
    public static final int FitWindow = 32768;
    public static final int GENERATION_MAX = 65535;
    public static final int HideMenubar = 8192;
    public static final int HideToolbar = 4096;
    public static final int HideWindowUI = 16384;
    public static final float NO_SPACE_CHAR_RATIO = 1.0E7f;
    public static final int NonFullScreenPageModeUseNone = 262144;
    public static final int NonFullScreenPageModeUseOC = 2097152;
    public static final int NonFullScreenPageModeUseOutlines = 524288;
    public static final int NonFullScreenPageModeUseThumbs = 1048576;
    public static final int PDFX1A2001 = 1;
    public static final int PDFX32002 = 2;
    public static final int PDFXNONE = 0;
    public static final int PageLayoutOneColumn = 2;
    public static final int PageLayoutSinglePage = 1;
    public static final int PageLayoutTwoColumnLeft = 4;
    public static final int PageLayoutTwoColumnRight = 8;
    public static final int PageLayoutTwoPageLeft = 16;
    public static final int PageLayoutTwoPageRight = 32;
    public static final int PageModeFullScreen = 512;
    public static final int PageModeUseAttachments = 2048;
    public static final int PageModeUseNone = 64;
    public static final int PageModeUseOC = 1024;
    public static final int PageModeUseOutlines = 128;
    public static final int PageModeUseThumbs = 256;
    public static final int PrintScalingNone = 16777216;
    public static final int RUN_DIRECTION_DEFAULT = 0;
    public static final int RUN_DIRECTION_LTR = 2;
    public static final int RUN_DIRECTION_NO_BIDI = 1;
    public static final int RUN_DIRECTION_RTL = 3;
    public static final int SIGNATURE_APPEND_ONLY = 2;
    public static final int SIGNATURE_EXISTS = 1;
    public static final float SPACE_CHAR_RATIO_DEFAULT = 2.5f;
    public static final int STANDARD_ENCRYPTION_128 = 1;
    public static final int STANDARD_ENCRYPTION_40 = 0;
    @Deprecated
    public static final boolean STRENGTH128BITS = true;
    @Deprecated
    public static final boolean STRENGTH40BITS = false;
    public static final char VERSION_1_2 = '2';
    public static final char VERSION_1_3 = '3';
    public static final char VERSION_1_4 = '4';
    public static final char VERSION_1_5 = '5';
    public static final char VERSION_1_6 = '6';
    public static final char VERSION_1_7 = '7';
    public static final int markAll = 0;
    public static final int markInlineElementsOnly = 1;
    protected HashMap<PdfStream, PdfIndirectReference> JBIG2Globals;
    protected PdfArray OCGLocked;
    protected PdfArray OCGRadioGroup;
    protected PdfOCProperties OCProperties;
    protected PdfBody body;
    protected int colorNumber;
    protected ICC_Profile colorProfile;
    protected int compressionLevel;
    protected PdfEncryption crypto;
    protected int currentPageNumber;
    protected PdfReaderInstance currentPdfReaderInstance;
    protected PdfDictionary defaultColorspace;
    protected PdfContentByte directContent;
    protected PdfContentByte directContentUnder;
    protected HashMap<ICachedColorSpace, ColorDetails> documentColors;
    protected HashMap<PdfDictionary, PdfObject[]> documentExtGState;
    protected LinkedHashMap<BaseFont, FontDetails> documentFonts;
    protected HashSet<PdfOCG> documentOCG;
    protected ArrayList<PdfOCG> documentOCGorder;
    protected HashMap<PdfPatternPainter, PdfName> documentPatterns;
    protected HashMap<Object, PdfObject[]> documentProperties;
    protected HashSet<PdfShadingPattern> documentShadingPatterns;
    protected HashSet<PdfShading> documentShadings;
    protected HashMap<ColorDetails, ColorDetails> documentSpotPatterns;
    protected PdfDictionary extraCatalog;
    protected int fontNumber;
    protected HashMap<PdfIndirectReference, Object[]> formXObjects;
    protected int formXObjectsCounter;
    protected boolean fullCompression;
    protected PdfDictionary group;
    protected PdfDictionary imageDictionary;
    private final HashMap<Long, PdfName> images;
    protected List<HashMap<String, Object>> newBookmarks;
    protected byte[] originalFileID;
    protected PdfDictionary pageDictEntries;
    private PdfPageEvent pageEvent;
    protected ArrayList<PdfIndirectReference> pageReferences;
    protected ColorDetails patternColorspaceCMYK;
    protected ColorDetails patternColorspaceGRAY;
    protected ColorDetails patternColorspaceRGB;
    protected int patternNumber;
    protected PdfDocument pdf;
    protected PdfIsoConformance pdfIsoConformance;
    protected PdfVersionImp pdf_version;
    protected long prevxref;
    protected HashMap<PdfReader, PdfReaderInstance> readerInstances;
    private boolean rgbTransparencyBlending;
    protected PdfPages root;
    protected int runDirection;
    private float spaceCharRatio;
    protected PdfStructureTreeRoot structureTreeRoot;
    protected PdfName tabs;
    protected boolean tagged;
    protected int taggingMode;
    protected TtfUnicodeWriter ttfUnicodeWriter;
    private boolean userProperties;
    protected byte[] xmpMetadata;
    protected XmpWriter xmpWriter;
    protected static Counter COUNTER = CounterFactory.getCounter(PdfWriter.class);
    public static final PdfName PDF_VERSION_1_2 = new PdfName("1.2");
    public static final PdfName PDF_VERSION_1_3 = new PdfName("1.3");
    public static final PdfName PDF_VERSION_1_4 = new PdfName("1.4");
    public static final PdfName PDF_VERSION_1_5 = new PdfName("1.5");
    public static final PdfName PDF_VERSION_1_6 = new PdfName("1.6");
    public static final PdfName PDF_VERSION_1_7 = new PdfName("1.7");
    public static final PdfName DOCUMENT_CLOSE = PdfName.WC;
    public static final PdfName WILL_SAVE = PdfName.WS;
    public static final PdfName DID_SAVE = PdfName.DS;
    public static final PdfName WILL_PRINT = PdfName.WP;
    public static final PdfName DID_PRINT = PdfName.DP;
    public static final PdfName PAGE_OPEN = PdfName.O;
    public static final PdfName PAGE_CLOSE = PdfName.C;
    private static final List<PdfName> standardStructElems_1_4 = Arrays.asList(PdfName.DOCUMENT, PdfName.PART, PdfName.ART, PdfName.SECT, PdfName.DIV, PdfName.BLOCKQUOTE, PdfName.CAPTION, PdfName.TOC, PdfName.TOCI, PdfName.INDEX, PdfName.NONSTRUCT, PdfName.PRIVATE, PdfName.P, PdfName.H, PdfName.H1, PdfName.H2, PdfName.H3, PdfName.H4, PdfName.H5, PdfName.H6, PdfName.L, PdfName.LBL, PdfName.LI, PdfName.LBODY, PdfName.TABLE, PdfName.TR, PdfName.TH, PdfName.TD, PdfName.SPAN, PdfName.QUOTE, PdfName.NOTE, PdfName.REFERENCE, PdfName.BIBENTRY, PdfName.CODE, PdfName.LINK, PdfName.FIGURE, PdfName.FORMULA, PdfName.FORM);
    private static final List<PdfName> standardStructElems_1_7 = Arrays.asList(PdfName.DOCUMENT, PdfName.PART, PdfName.ART, PdfName.SECT, PdfName.DIV, PdfName.BLOCKQUOTE, PdfName.CAPTION, PdfName.TOC, PdfName.TOCI, PdfName.INDEX, PdfName.NONSTRUCT, PdfName.PRIVATE, PdfName.P, PdfName.H, PdfName.H1, PdfName.H2, PdfName.H3, PdfName.H4, PdfName.H5, PdfName.H6, PdfName.L, PdfName.LBL, PdfName.LI, PdfName.LBODY, PdfName.TABLE, PdfName.TR, PdfName.TH, PdfName.TD, PdfName.THEAD, PdfName.TBODY, PdfName.TFOOT, PdfName.SPAN, PdfName.QUOTE, PdfName.NOTE, PdfName.REFERENCE, PdfName.BIBENTRY, PdfName.CODE, PdfName.LINK, PdfName.ANNOT, PdfName.RUBY, PdfName.RB, PdfName.RT, PdfName.RP, PdfName.WARICHU, PdfName.WT, PdfName.WP, PdfName.FIGURE, PdfName.FORMULA, PdfName.FORM);

    public static class PdfBody {
        private static final int OBJSINSTREAM = 200;
        protected int currentObjNum;
        protected ByteBuffer index;
        protected long position;
        protected int refnum;
        protected ByteBuffer streamObjects;
        protected final PdfWriter writer;
        protected int numObj = 0;
        protected final TreeSet<PdfCrossReference> xrefs = new TreeSet<>();

        public static class PdfCrossReference implements Comparable<PdfCrossReference> {
            private final int generation;
            private final long offset;
            private final int refnum;
            private final int type;

            public PdfCrossReference(int refnum, long offset, int generation) {
                this.type = 0;
                this.offset = offset;
                this.refnum = refnum;
                this.generation = generation;
            }

            public PdfCrossReference(int refnum, long offset) {
                this.type = 1;
                this.offset = offset;
                this.refnum = refnum;
                this.generation = 0;
            }

            public PdfCrossReference(int type, int refnum, long offset, int generation) {
                this.type = type;
                this.offset = offset;
                this.refnum = refnum;
                this.generation = generation;
            }

            public int getRefnum() {
                return this.refnum;
            }

            public void toPdf(OutputStream os) throws IOException {
                StringBuffer off = new StringBuffer("0000000000").append(this.offset);
                off.delete(0, off.length() - 10);
                StringBuffer gen = new StringBuffer("00000").append(this.generation);
                gen.delete(0, gen.length() - 5);
                off.append(' ').append(gen).append(this.generation == 65535 ? " f \n" : " n \n");
                os.write(DocWriter.getISOBytes(off.toString()));
            }

            public void toPdf(int midSize, OutputStream os) throws IOException {
                os.write((byte) this.type);
                while (true) {
                    midSize--;
                    if (midSize >= 0) {
                        os.write((byte) ((this.offset >>> (midSize * 8)) & 255));
                    } else {
                        os.write((byte) ((this.generation >>> 8) & 255));
                        os.write((byte) (this.generation & 255));
                        return;
                    }
                }
            }

            @Override
            public int compareTo(PdfCrossReference other) {
                if (this.refnum < other.refnum) {
                    return -1;
                }
                return this.refnum == other.refnum ? 0 : 1;
            }

            public boolean equals(Object obj) {
                if (obj instanceof PdfCrossReference) {
                    PdfCrossReference other = (PdfCrossReference) obj;
                    return this.refnum == other.refnum;
                }
                return false;
            }

            public int hashCode() {
                return this.refnum;
            }
        }

        public PdfBody(PdfWriter writer) {
            this.xrefs.add(new PdfCrossReference(0, 0L, 65535));
            this.position = writer.getOs().getCounter();
            this.refnum = 1;
            this.writer = writer;
        }

        public void setRefnum(int refnum) {
            this.refnum = refnum;
        }

        protected PdfCrossReference addToObjStm(PdfObject obj, int nObj) throws IOException {
            if (this.numObj >= 200) {
                flushObjStm();
            }
            if (this.index == null) {
                this.index = new ByteBuffer();
                this.streamObjects = new ByteBuffer();
                this.currentObjNum = getIndirectReferenceNumber();
                this.numObj = 0;
            }
            int p = this.streamObjects.size();
            int idx = this.numObj;
            this.numObj = idx + 1;
            PdfEncryption enc = this.writer.crypto;
            this.writer.crypto = null;
            obj.toPdf(this.writer, this.streamObjects);
            this.writer.crypto = enc;
            this.streamObjects.append(' ');
            this.index.append(nObj).append(' ').append(p).append(' ');
            return new PdfCrossReference(2, nObj, this.currentObjNum, idx);
        }

        public void flushObjStm() throws IOException {
            if (this.numObj != 0) {
                int first = this.index.size();
                this.index.append(this.streamObjects);
                PdfStream stream = new PdfStream(this.index.toByteArray());
                stream.flateCompress(this.writer.getCompressionLevel());
                stream.put(PdfName.TYPE, PdfName.OBJSTM);
                stream.put(PdfName.N, new PdfNumber(this.numObj));
                stream.put(PdfName.FIRST, new PdfNumber(first));
                add(stream, this.currentObjNum);
                this.index = null;
                this.streamObjects = null;
                this.numObj = 0;
            }
        }

        public PdfIndirectObject add(PdfObject object) throws IOException {
            return add(object, getIndirectReferenceNumber());
        }

        PdfIndirectObject add(PdfObject object, boolean inObjStm) throws IOException {
            return add(object, getIndirectReferenceNumber(), 0, inObjStm);
        }

        public PdfIndirectReference getPdfIndirectReference() {
            return new PdfIndirectReference(0, getIndirectReferenceNumber());
        }

        protected int getIndirectReferenceNumber() {
            int n = this.refnum;
            this.refnum = n + 1;
            this.xrefs.add(new PdfCrossReference(n, 0L, 65535));
            return n;
        }

        public PdfIndirectObject add(PdfObject object, PdfIndirectReference ref) throws IOException {
            return add(object, ref, true);
        }

        PdfIndirectObject add(PdfObject object, PdfIndirectReference ref, boolean inObjStm) throws IOException {
            return add(object, ref.getNumber(), ref.getGeneration(), inObjStm);
        }

        PdfIndirectObject add(PdfObject object, int refNumber) throws IOException {
            return add(object, refNumber, 0, true);
        }

        public PdfIndirectObject add(PdfObject object, int refNumber, int generation, boolean inObjStm) throws IOException {
            if (inObjStm && object.canBeInObjStm() && this.writer.isFullCompression()) {
                PdfCrossReference pxref = addToObjStm(object, refNumber);
                PdfIndirectObject indirect = new PdfIndirectObject(refNumber, object, this.writer);
                if (!this.xrefs.add(pxref)) {
                    this.xrefs.remove(pxref);
                    this.xrefs.add(pxref);
                    return indirect;
                }
                return indirect;
            } else if (this.writer.isFullCompression()) {
                PdfIndirectObject indirect2 = new PdfIndirectObject(refNumber, object, this.writer);
                write(indirect2, refNumber);
                return indirect2;
            } else {
                PdfIndirectObject indirect3 = new PdfIndirectObject(refNumber, generation, object, this.writer);
                write(indirect3, refNumber, generation);
                return indirect3;
            }
        }

        protected void write(PdfIndirectObject indirect, int refNumber) throws IOException {
            PdfCrossReference pxref = new PdfCrossReference(refNumber, this.position);
            if (!this.xrefs.add(pxref)) {
                this.xrefs.remove(pxref);
                this.xrefs.add(pxref);
            }
            indirect.writeTo(this.writer.getOs());
            this.position = this.writer.getOs().getCounter();
        }

        protected void write(PdfIndirectObject indirect, int refNumber, int generation) throws IOException {
            PdfCrossReference pxref = new PdfCrossReference(refNumber, this.position, generation);
            if (!this.xrefs.add(pxref)) {
                this.xrefs.remove(pxref);
                this.xrefs.add(pxref);
            }
            indirect.writeTo(this.writer.getOs());
            this.position = this.writer.getOs().getCounter();
        }

        public long offset() {
            return this.position;
        }

        public int size() {
            return Math.max(this.xrefs.last().getRefnum() + 1, this.refnum);
        }

        public void writeCrossReferenceTable(OutputStream os, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, long prevxref) throws IOException {
            int refNumber = 0;
            if (this.writer.isFullCompression()) {
                flushObjStm();
                refNumber = getIndirectReferenceNumber();
                this.xrefs.add(new PdfCrossReference(refNumber, this.position));
            }
            PdfCrossReference entry = this.xrefs.first();
            int first = entry.getRefnum();
            int len = 0;
            ArrayList<Integer> sections = new ArrayList<>();
            Iterator i$ = this.xrefs.iterator();
            while (i$.hasNext()) {
                PdfCrossReference pdfCrossReference = i$.next();
                if (first + len == pdfCrossReference.getRefnum()) {
                    len++;
                } else {
                    sections.add(Integer.valueOf(first));
                    sections.add(Integer.valueOf(len));
                    first = pdfCrossReference.getRefnum();
                    len = 1;
                }
            }
            sections.add(Integer.valueOf(first));
            sections.add(Integer.valueOf(len));
            if (this.writer.isFullCompression()) {
                int mid = 5;
                long mask = 1095216660480L;
                while (mid > 1 && (this.position & mask) == 0) {
                    mask >>>= 8;
                    mid--;
                }
                ByteBuffer buf = new ByteBuffer();
                Iterator i$2 = this.xrefs.iterator();
                while (i$2.hasNext()) {
                    PdfCrossReference element = i$2.next();
                    PdfCrossReference entry2 = element;
                    entry2.toPdf(mid, buf);
                }
                PdfStream xr = new PdfStream(buf.toByteArray());
                xr.flateCompress(this.writer.getCompressionLevel());
                xr.put(PdfName.SIZE, new PdfNumber(size()));
                xr.put(PdfName.ROOT, root);
                if (info != null) {
                    xr.put(PdfName.INFO, info);
                }
                if (encryption != null) {
                    xr.put(PdfName.ENCRYPT, encryption);
                }
                if (fileID != null) {
                    xr.put(PdfName.ID, fileID);
                }
                xr.put(PdfName.W, new PdfArray(new int[]{1, mid, 2}));
                xr.put(PdfName.TYPE, PdfName.XREF);
                PdfArray idx = new PdfArray();
                for (int k = 0; k < sections.size(); k++) {
                    idx.add(new PdfNumber(sections.get(k).intValue()));
                }
                xr.put(PdfName.INDEX, idx);
                if (prevxref > 0) {
                    xr.put(PdfName.PREV, new PdfNumber(prevxref));
                }
                PdfEncryption enc = this.writer.crypto;
                this.writer.crypto = null;
                PdfIndirectObject indirect = new PdfIndirectObject(refNumber, xr, this.writer);
                indirect.writeTo(this.writer.getOs());
                this.writer.crypto = enc;
                return;
            }
            os.write(DocWriter.getISOBytes("xref\n"));
            Iterator<PdfCrossReference> i = this.xrefs.iterator();
            for (int k2 = 0; k2 < sections.size(); k2 += 2) {
                int first2 = sections.get(k2).intValue();
                int len2 = sections.get(k2 + 1).intValue();
                os.write(DocWriter.getISOBytes(String.valueOf(first2)));
                os.write(DocWriter.getISOBytes(" "));
                os.write(DocWriter.getISOBytes(String.valueOf(len2)));
                os.write(10);
                while (true) {
                    int len3 = len2;
                    len2 = len3 - 1;
                    if (len3 > 0) {
                        PdfCrossReference entry3 = i.next();
                        entry3.toPdf(os);
                    }
                }
            }
        }
    }

    public static class PdfTrailer extends PdfDictionary {
        long offset;

        public PdfTrailer(int size, long offset, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, long prevxref) {
            this.offset = offset;
            put(PdfName.SIZE, new PdfNumber(size));
            put(PdfName.ROOT, root);
            if (info != null) {
                put(PdfName.INFO, info);
            }
            if (encryption != null) {
                put(PdfName.ENCRYPT, encryption);
            }
            if (fileID != null) {
                put(PdfName.ID, fileID);
            }
            if (prevxref > 0) {
                put(PdfName.PREV, new PdfNumber(prevxref));
            }
        }

        @Override
        public void toPdf(PdfWriter writer, OutputStream os) throws IOException {
            PdfWriter.checkPdfIsoConformance(writer, 8, this);
            os.write(DocWriter.getISOBytes("trailer\n"));
            super.toPdf(null, os);
            os.write(10);
            PdfWriter.writeKeyInfo(os);
            os.write(DocWriter.getISOBytes("startxref\n"));
            os.write(DocWriter.getISOBytes(String.valueOf(this.offset)));
            os.write(DocWriter.getISOBytes("\n%%EOF\n"));
        }
    }

    protected Counter getCounter() {
        return COUNTER;
    }

    protected PdfWriter() {
        this.root = new PdfPages(this);
        this.pageReferences = new ArrayList<>();
        this.currentPageNumber = 1;
        this.tabs = null;
        this.pageDictEntries = new PdfDictionary();
        this.prevxref = 0L;
        this.originalFileID = null;
        this.pdf_version = new PdfVersionImp();
        this.xmpMetadata = null;
        this.xmpWriter = null;
        this.pdfIsoConformance = initPdfIsoConformance();
        this.fullCompression = false;
        this.compressionLevel = -1;
        this.documentFonts = new LinkedHashMap<>();
        this.fontNumber = 1;
        this.formXObjects = new HashMap<>();
        this.formXObjectsCounter = 1;
        this.readerInstances = new HashMap<>();
        this.documentColors = new HashMap<>();
        this.colorNumber = 1;
        this.documentPatterns = new HashMap<>();
        this.patternNumber = 1;
        this.documentShadingPatterns = new HashSet<>();
        this.documentShadings = new HashSet<>();
        this.documentExtGState = new HashMap<>();
        this.documentProperties = new HashMap<>();
        this.tagged = false;
        this.taggingMode = 1;
        this.documentOCG = new HashSet<>();
        this.documentOCGorder = new ArrayList<>();
        this.OCGRadioGroup = new PdfArray();
        this.OCGLocked = new PdfArray();
        this.spaceCharRatio = 2.5f;
        this.runDirection = 1;
        this.defaultColorspace = new PdfDictionary();
        this.documentSpotPatterns = new HashMap<>();
        this.imageDictionary = new PdfDictionary();
        this.images = new HashMap<>();
        this.JBIG2Globals = new HashMap<>();
        this.ttfUnicodeWriter = null;
    }

    public PdfWriter(PdfDocument document, OutputStream os) {
        super(document, os);
        this.root = new PdfPages(this);
        this.pageReferences = new ArrayList<>();
        this.currentPageNumber = 1;
        this.tabs = null;
        this.pageDictEntries = new PdfDictionary();
        this.prevxref = 0L;
        this.originalFileID = null;
        this.pdf_version = new PdfVersionImp();
        this.xmpMetadata = null;
        this.xmpWriter = null;
        this.pdfIsoConformance = initPdfIsoConformance();
        this.fullCompression = false;
        this.compressionLevel = -1;
        this.documentFonts = new LinkedHashMap<>();
        this.fontNumber = 1;
        this.formXObjects = new HashMap<>();
        this.formXObjectsCounter = 1;
        this.readerInstances = new HashMap<>();
        this.documentColors = new HashMap<>();
        this.colorNumber = 1;
        this.documentPatterns = new HashMap<>();
        this.patternNumber = 1;
        this.documentShadingPatterns = new HashSet<>();
        this.documentShadings = new HashSet<>();
        this.documentExtGState = new HashMap<>();
        this.documentProperties = new HashMap<>();
        this.tagged = false;
        this.taggingMode = 1;
        this.documentOCG = new HashSet<>();
        this.documentOCGorder = new ArrayList<>();
        this.OCGRadioGroup = new PdfArray();
        this.OCGLocked = new PdfArray();
        this.spaceCharRatio = 2.5f;
        this.runDirection = 1;
        this.defaultColorspace = new PdfDictionary();
        this.documentSpotPatterns = new HashMap<>();
        this.imageDictionary = new PdfDictionary();
        this.images = new HashMap<>();
        this.JBIG2Globals = new HashMap<>();
        this.ttfUnicodeWriter = null;
        this.pdf = document;
        this.directContentUnder = new PdfContentByte(this);
        this.directContent = this.directContentUnder.getDuplicate();
    }

    public static PdfWriter getInstance(Document document, OutputStream os) throws DocumentException {
        PdfDocument pdf = new PdfDocument();
        document.addDocListener(pdf);
        PdfWriter writer = new PdfWriter(pdf, os);
        pdf.addWriter(writer);
        return writer;
    }

    public static PdfWriter getInstance(Document document, OutputStream os, DocListener listener) throws DocumentException {
        PdfDocument pdf = new PdfDocument();
        pdf.addDocListener(listener);
        document.addDocListener(pdf);
        PdfWriter writer = new PdfWriter(pdf, os);
        pdf.addWriter(writer);
        return writer;
    }

    public PdfDocument getPdfDocument() {
        return this.pdf;
    }

    public PdfDictionary getInfo() {
        return this.pdf.getInfo();
    }

    public float getVerticalPosition(boolean ensureNewLine) {
        return this.pdf.getVerticalPosition(ensureNewLine);
    }

    public void setInitialLeading(float leading) throws DocumentException {
        if (this.open) {
            throw new DocumentException(MessageLocalization.getComposedMessage("you.can.t.set.the.initial.leading.if.the.document.is.already.open", new Object[0]));
        }
        this.pdf.setLeading(leading);
    }

    public PdfContentByte getDirectContent() {
        if (!this.open) {
            throw new RuntimeException(MessageLocalization.getComposedMessage("the.document.is.not.open", new Object[0]));
        }
        return this.directContent;
    }

    public PdfContentByte getDirectContentUnder() {
        if (!this.open) {
            throw new RuntimeException(MessageLocalization.getComposedMessage("the.document.is.not.open", new Object[0]));
        }
        return this.directContentUnder;
    }

    public void resetContent() {
        this.directContent.reset();
        this.directContentUnder.reset();
    }

    public ICC_Profile getColorProfile() {
        return this.colorProfile;
    }

    public void addLocalDestinations(TreeMap<String, PdfDocument.Destination> desto) throws IOException {
        for (Map.Entry<String, PdfDocument.Destination> entry : desto.entrySet()) {
            String name = entry.getKey();
            PdfDocument.Destination dest = entry.getValue();
            PdfDestination destination = dest.destination;
            if (dest.reference == null) {
                dest.reference = getPdfIndirectReference();
            }
            if (destination == null) {
                addToBody(new PdfString("invalid_" + name), dest.reference);
            } else {
                addToBody(destination, dest.reference);
            }
        }
    }

    public PdfIndirectObject addToBody(PdfObject object) throws IOException {
        PdfIndirectObject iobj = this.body.add(object);
        return iobj;
    }

    public PdfIndirectObject addToBody(PdfObject object, boolean inObjStm) throws IOException {
        PdfIndirectObject iobj = this.body.add(object, inObjStm);
        return iobj;
    }

    public PdfIndirectObject addToBody(PdfObject object, PdfIndirectReference ref) throws IOException {
        PdfIndirectObject iobj = this.body.add(object, ref);
        return iobj;
    }

    public PdfIndirectObject addToBody(PdfObject object, PdfIndirectReference ref, boolean inObjStm) throws IOException {
        PdfIndirectObject iobj = this.body.add(object, ref, inObjStm);
        return iobj;
    }

    public PdfIndirectObject addToBody(PdfObject object, int refNumber) throws IOException {
        PdfIndirectObject iobj = this.body.add(object, refNumber);
        return iobj;
    }

    public PdfIndirectObject addToBody(PdfObject object, int refNumber, boolean inObjStm) throws IOException {
        PdfIndirectObject iobj = this.body.add(object, refNumber, 0, inObjStm);
        return iobj;
    }

    public PdfIndirectReference getPdfIndirectReference() {
        return this.body.getPdfIndirectReference();
    }

    public int getIndirectReferenceNumber() {
        return this.body.getIndirectReferenceNumber();
    }

    public OutputStreamCounter getOs() {
        return this.os;
    }

    protected PdfDictionary getCatalog(PdfIndirectReference rootObj) {
        PdfDictionary catalog = this.pdf.getCatalog(rootObj);
        buildStructTreeRootForTagged(catalog);
        if (!this.documentOCG.isEmpty()) {
            fillOCProperties(false);
            catalog.put(PdfName.OCPROPERTIES, this.OCProperties);
        }
        return catalog;
    }

    public void buildStructTreeRootForTagged(PdfDictionary catalog) {
        if (this.tagged) {
            try {
                getStructureTreeRoot().buildTree();
                catalog.put(PdfName.STRUCTTREEROOT, this.structureTreeRoot.getReference());
                PdfDictionary mi = new PdfDictionary();
                mi.put(PdfName.MARKED, PdfBoolean.PDFTRUE);
                if (this.userProperties) {
                    mi.put(PdfName.USERPROPERTIES, PdfBoolean.PDFTRUE);
                }
                catalog.put(PdfName.MARKINFO, mi);
            } catch (Exception e) {
                throw new ExceptionConverter(e);
            }
        }
    }

    public PdfDictionary getExtraCatalog() {
        if (this.extraCatalog == null) {
            this.extraCatalog = new PdfDictionary();
        }
        return this.extraCatalog;
    }

    public void addPageDictEntry(PdfName key, PdfObject object) {
        this.pageDictEntries.put(key, object);
    }

    public PdfDictionary getPageDictEntries() {
        return this.pageDictEntries;
    }

    public void resetPageDictEntries() {
        this.pageDictEntries = new PdfDictionary();
    }

    public void setLinearPageMode() {
        this.root.setLinearMode(null);
    }

    public int reorderPages(int[] order) throws DocumentException {
        return this.root.reorderPages(order);
    }

    public PdfIndirectReference getPageReference(int page) {
        int page2 = page - 1;
        if (page2 < 0) {
            throw new IndexOutOfBoundsException(MessageLocalization.getComposedMessage("the.page.number.must.be.gt.eq.1", new Object[0]));
        }
        if (page2 < this.pageReferences.size()) {
            PdfIndirectReference ref = this.pageReferences.get(page2);
            if (ref == null) {
                PdfIndirectReference ref2 = this.body.getPdfIndirectReference();
                this.pageReferences.set(page2, ref2);
                return ref2;
            }
            return ref;
        }
        int empty = page2 - this.pageReferences.size();
        for (int k = 0; k < empty; k++) {
            this.pageReferences.add(null);
        }
        PdfIndirectReference ref3 = this.body.getPdfIndirectReference();
        this.pageReferences.add(ref3);
        return ref3;
    }

    public int getPageNumber() {
        return this.pdf.getPageNumber();
    }

    public PdfIndirectReference getCurrentPage() {
        return getPageReference(this.currentPageNumber);
    }

    public int getCurrentPageNumber() {
        return this.currentPageNumber;
    }

    public void setPageViewport(PdfArray vp) {
        addPageDictEntry(PdfName.VP, vp);
    }

    public void setTabs(PdfName tabs) {
        this.tabs = tabs;
    }

    public PdfName getTabs() {
        return this.tabs;
    }

    public PdfIndirectReference add(PdfPage page, PdfContents contents) throws PdfException {
        if (!this.open) {
            throw new PdfException(MessageLocalization.getComposedMessage("the.document.is.not.open", new Object[0]));
        }
        try {
            PdfIndirectObject object = addToBody(contents);
            page.add(object.getIndirectReference());
            if (this.group != null) {
                page.put(PdfName.GROUP, this.group);
                this.group = null;
            } else if (this.rgbTransparencyBlending) {
                PdfDictionary pp = new PdfDictionary();
                pp.put(PdfName.TYPE, PdfName.GROUP);
                pp.put(PdfName.S, PdfName.TRANSPARENCY);
                pp.put(PdfName.CS, PdfName.DEVICERGB);
                page.put(PdfName.GROUP, pp);
            }
            this.root.addPage(page);
            this.currentPageNumber++;
            return null;
        } catch (IOException ioe) {
            throw new ExceptionConverter(ioe);
        }
    }

    public void setPageEvent(PdfPageEvent event) {
        if (event != null) {
            if (this.pageEvent != null) {
                if (!(this.pageEvent instanceof PdfPageEventForwarder)) {
                    PdfPageEventForwarder forward = new PdfPageEventForwarder();
                    forward.addPageEvent(this.pageEvent);
                    forward.addPageEvent(event);
                    this.pageEvent = forward;
                    return;
                }
                ((PdfPageEventForwarder) this.pageEvent).addPageEvent(event);
                return;
            }
            this.pageEvent = event;
            return;
        }
        this.pageEvent = null;
    }

    public PdfPageEvent getPageEvent() {
        return this.pageEvent;
    }

    @Override
    public void open() {
        super.open();
        try {
            this.pdf_version.writeHeader(this.os);
            this.body = new PdfBody(this);
            if (isPdfX() && ((PdfXConformanceImp) this.pdfIsoConformance).isPdfX32002()) {
                PdfDictionary sec = new PdfDictionary();
                sec.put(PdfName.GAMMA, new PdfArray(new float[]{2.2f, 2.2f, 2.2f}));
                sec.put(PdfName.MATRIX, new PdfArray(new float[]{0.4124f, 0.2126f, 0.0193f, 0.3576f, 0.7152f, 0.1192f, 0.1805f, 0.0722f, 0.9505f}));
                sec.put(PdfName.WHITEPOINT, new PdfArray(new float[]{0.9505f, 1.0f, 1.089f}));
                PdfArray arr = new PdfArray(PdfName.CALRGB);
                arr.add(sec);
                setDefaultColorspace(PdfName.DEFAULTRGB, addToBody(arr).getIndirectReference());
            }
        } catch (IOException ioe) {
            throw new ExceptionConverter(ioe);
        }
    }

    @Override
    public void close() {
        PdfObject fileID;
        if (this.open) {
            if (this.currentPageNumber - 1 != this.pageReferences.size()) {
                throw new RuntimeException("The page " + this.pageReferences.size() + " was requested but the document has only " + (this.currentPageNumber - 1) + " pages.");
            }
            this.pdf.close();
            try {
                addSharedObjectsToBody();
                Iterator i$ = this.documentOCG.iterator();
                while (i$.hasNext()) {
                    PdfOCG layer = i$.next();
                    addToBody(layer.getPdfObject(), layer.getRef());
                }
                PdfIndirectReference rootRef = this.root.writePageTree();
                PdfDictionary catalog = getCatalog(rootRef);
                if (!this.documentOCG.isEmpty()) {
                    checkPdfIsoConformance(this, 7, this.OCProperties);
                }
                if (this.xmpMetadata == null && this.xmpWriter != null) {
                    try {
                        try {
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            this.xmpWriter.serialize(baos);
                            this.xmpWriter.close();
                            this.xmpMetadata = baos.toByteArray();
                        } catch (XMPException e) {
                            this.xmpWriter = null;
                        }
                    } catch (IOException e2) {
                        this.xmpWriter = null;
                    }
                }
                if (this.xmpMetadata != null) {
                    PdfStream xmp = new PdfStream(this.xmpMetadata);
                    xmp.put(PdfName.TYPE, PdfName.METADATA);
                    xmp.put(PdfName.SUBTYPE, PdfName.XML);
                    if (this.crypto != null && !this.crypto.isMetadataEncrypted()) {
                        PdfArray ar = new PdfArray();
                        ar.add(PdfName.CRYPT);
                        xmp.put(PdfName.FILTER, ar);
                    }
                    catalog.put(PdfName.METADATA, this.body.add(xmp).getIndirectReference());
                }
                if (isPdfX()) {
                    completeInfoDictionary(getInfo());
                    completeExtraCatalog(getExtraCatalog());
                }
                if (this.extraCatalog != null) {
                    catalog.mergeDifferent(this.extraCatalog);
                }
                writeOutlines(catalog, false);
                PdfIndirectObject indirectCatalog = addToBody((PdfObject) catalog, false);
                PdfIndirectObject infoObj = addToBody((PdfObject) getInfo(), false);
                PdfIndirectReference encryption = null;
                this.body.flushObjStm();
                boolean isModified = this.originalFileID != null;
                if (this.crypto != null) {
                    PdfIndirectObject encryptionObject = addToBody(this.crypto.getEncryptionDictionary(), false);
                    encryption = encryptionObject.getIndirectReference();
                    fileID = this.crypto.getFileID(isModified);
                } else {
                    fileID = PdfEncryption.createInfoId(isModified ? this.originalFileID : PdfEncryption.createDocumentId(), isModified);
                }
                this.body.writeCrossReferenceTable(this.os, indirectCatalog.getIndirectReference(), infoObj.getIndirectReference(), encryption, fileID, this.prevxref);
                if (this.fullCompression) {
                    writeKeyInfo(this.os);
                    this.os.write(getISOBytes("startxref\n"));
                    this.os.write(getISOBytes(String.valueOf(this.body.offset())));
                    this.os.write(getISOBytes("\n%%EOF\n"));
                } else {
                    PdfTrailer trailer = new PdfTrailer(this.body.size(), this.body.offset(), indirectCatalog.getIndirectReference(), infoObj.getIndirectReference(), encryption, fileID, this.prevxref);
                    trailer.toPdf(this, this.os);
                }
                super.close();
            } catch (IOException ioe) {
                throw new ExceptionConverter(ioe);
            }
        }
        getCounter().written(this.os.getCounter());
    }

    protected void addXFormsToBody() throws IOException {
        for (Object[] objs : this.formXObjects.values()) {
            PdfTemplate template = (PdfTemplate) objs[1];
            if (template == null || !(template.getIndirectReference() instanceof PRIndirectReference)) {
                if (template != null && template.getType() == 1) {
                    addToBody(template.getFormXObject(this.compressionLevel), template.getIndirectReference());
                }
            }
        }
    }

    public void addSharedObjectsToBody() throws IOException {
        for (FontDetails details : this.documentFonts.values()) {
            details.writeFont(this);
        }
        addXFormsToBody();
        for (PdfReaderInstance element : this.readerInstances.values()) {
            this.currentPdfReaderInstance = element;
            this.currentPdfReaderInstance.writeAllPages();
        }
        this.currentPdfReaderInstance = null;
        for (ColorDetails color : this.documentColors.values()) {
            addToBody(color.getPdfObject(this), color.getIndirectReference());
        }
        for (PdfPatternPainter pat : this.documentPatterns.keySet()) {
            addToBody(pat.getPattern(this.compressionLevel), pat.getIndirectReference());
        }
        Iterator i$ = this.documentShadingPatterns.iterator();
        while (i$.hasNext()) {
            PdfShadingPattern shadingPattern = i$.next();
            shadingPattern.addToBody();
        }
        Iterator i$2 = this.documentShadings.iterator();
        while (i$2.hasNext()) {
            PdfShading shading = i$2.next();
            shading.addToBody();
        }
        for (Map.Entry<PdfDictionary, PdfObject[]> entry : this.documentExtGState.entrySet()) {
            PdfDictionary gstate = entry.getKey();
            PdfObject[] obj = entry.getValue();
            addToBody(gstate, (PdfIndirectReference) obj[1]);
        }
        for (Map.Entry<Object, PdfObject[]> entry2 : this.documentProperties.entrySet()) {
            Object prop = entry2.getKey();
            PdfObject[] obj2 = entry2.getValue();
            if (prop instanceof PdfLayerMembership) {
                PdfLayerMembership layer = (PdfLayerMembership) prop;
                addToBody(layer.getPdfObject(), layer.getRef());
            } else if ((prop instanceof PdfDictionary) && !(prop instanceof PdfLayer)) {
                addToBody((PdfDictionary) prop, (PdfIndirectReference) obj2[1]);
            }
        }
    }

    public PdfOutline getRootOutline() {
        return this.directContent.getRootOutline();
    }

    public void setOutlines(List<HashMap<String, Object>> outlines) {
        this.newBookmarks = outlines;
    }

    public void writeOutlines(PdfDictionary catalog, boolean namedAsNames) throws IOException {
        if (this.newBookmarks != null && !this.newBookmarks.isEmpty()) {
            PdfDictionary top = new PdfDictionary();
            PdfIndirectReference topRef = getPdfIndirectReference();
            Object[] kids = SimpleBookmark.iterateOutlines(this, topRef, this.newBookmarks, namedAsNames);
            top.put(PdfName.FIRST, (PdfIndirectReference) kids[0]);
            top.put(PdfName.LAST, (PdfIndirectReference) kids[1]);
            top.put(PdfName.COUNT, new PdfNumber(((Integer) kids[2]).intValue()));
            addToBody(top, topRef);
            catalog.put(PdfName.OUTLINES, topRef);
        }
    }

    @Override
    public void setPdfVersion(char version) {
        this.pdf_version.setPdfVersion(version);
    }

    @Override
    public void setAtLeastPdfVersion(char version) {
        this.pdf_version.setAtLeastPdfVersion(version);
    }

    @Override
    public void setPdfVersion(PdfName version) {
        this.pdf_version.setPdfVersion(version);
    }

    @Override
    public void addDeveloperExtension(PdfDeveloperExtension de) {
        this.pdf_version.addDeveloperExtension(de);
    }

    public PdfVersionImp getPdfVersion() {
        return this.pdf_version;
    }

    public void setViewerPreferences(int preferences) {
        this.pdf.setViewerPreferences(preferences);
    }

    public void addViewerPreference(PdfName key, PdfObject value) {
        this.pdf.addViewerPreference(key, value);
    }

    public void setPageLabels(PdfPageLabels pageLabels) {
        this.pdf.setPageLabels(pageLabels);
    }

    public void addNamedDestinations(Map<String, String> map, int page_offset) {
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String dest = entry.getValue();
            int page = Integer.parseInt(dest.substring(0, dest.indexOf(" ")));
            PdfDestination destination = new PdfDestination(dest.substring(dest.indexOf(" ") + 1));
            addNamedDestination(entry.getKey(), page + page_offset, destination);
        }
    }

    public void addNamedDestination(String name, int page, PdfDestination dest) {
        dest.addPage(getPageReference(page));
        this.pdf.localDestination(name, dest);
    }

    public void addJavaScript(PdfAction js) {
        this.pdf.addJavaScript(js);
    }

    public void addJavaScript(String code, boolean unicode) {
        addJavaScript(PdfAction.javaScript(code, this, unicode));
    }

    public void addJavaScript(String code) {
        addJavaScript(code, false);
    }

    public void addJavaScript(String name, PdfAction js) {
        this.pdf.addJavaScript(name, js);
    }

    public void addJavaScript(String name, String code, boolean unicode) {
        addJavaScript(name, PdfAction.javaScript(code, this, unicode));
    }

    public void addJavaScript(String name, String code) {
        addJavaScript(name, code, false);
    }

    public void addFileAttachment(String description, byte[] fileStore, String file, String fileDisplay) throws IOException {
        addFileAttachment(description, PdfFileSpecification.fileEmbedded(this, file, fileDisplay, fileStore));
    }

    public void addFileAttachment(String description, PdfFileSpecification fs) throws IOException {
        this.pdf.addFileAttachment(description, fs);
    }

    public void addFileAttachment(PdfFileSpecification fs) throws IOException {
        addFileAttachment(null, fs);
    }

    public void setOpenAction(String name) {
        this.pdf.setOpenAction(name);
    }

    public void setOpenAction(PdfAction action) {
        this.pdf.setOpenAction(action);
    }

    public void setAdditionalAction(PdfName actionType, PdfAction action) throws DocumentException {
        if (!actionType.equals(DOCUMENT_CLOSE) && !actionType.equals(WILL_SAVE) && !actionType.equals(DID_SAVE) && !actionType.equals(WILL_PRINT) && !actionType.equals(DID_PRINT)) {
            throw new DocumentException(MessageLocalization.getComposedMessage("invalid.additional.action.type.1", actionType.toString()));
        }
        this.pdf.addAdditionalAction(actionType, action);
    }

    public void setCollection(PdfCollection collection) {
        setAtLeastPdfVersion(VERSION_1_7);
        this.pdf.setCollection(collection);
    }

    @Override
    public PdfAcroForm getAcroForm() {
        return this.pdf.getAcroForm();
    }

    public void addAnnotation(PdfAnnotation annot) {
        this.pdf.addAnnotation(annot);
    }

    void addAnnotation(PdfAnnotation annot, int page) {
        addAnnotation(annot);
    }

    @Override
    public void addCalculationOrder(PdfFormField annot) {
        this.pdf.addCalculationOrder(annot);
    }

    public void setSigFlags(int f) {
        this.pdf.setSigFlags(f);
    }

    public void setLanguage(String language) {
        this.pdf.setLanguage(language);
    }

    public void setXmpMetadata(byte[] xmpMetadata) {
        this.xmpMetadata = xmpMetadata;
    }

    public void setPageXmpMetadata(byte[] xmpMetadata) throws IOException {
        this.pdf.setXmpMetadata(xmpMetadata);
    }

    public XmpWriter getXmpWriter() {
        return this.xmpWriter;
    }

    public void createXmpMetadata() {
        try {
            this.xmpWriter = createXmpWriter((ByteArrayOutputStream) null, this.pdf.getInfo());
            if (isTagged()) {
                try {
                    this.xmpWriter.getXmpMeta().setPropertyInteger(XMPConst.NS_PDFUA_ID, PdfProperties.PART, 1, new PropertyOptions(PropertyOptions.SEPARATE_NODE));
                } catch (XMPException e) {
                    throw new ExceptionConverter(e);
                }
            }
            this.xmpMetadata = null;
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    protected PdfIsoConformance initPdfIsoConformance() {
        return new PdfXConformanceImp(this);
    }

    public void setPDFXConformance(int pdfx) {
        if ((this.pdfIsoConformance instanceof PdfXConformanceImp) && ((PdfXConformance) this.pdfIsoConformance).getPDFXConformance() != pdfx) {
            if (this.pdf.isOpen()) {
                throw new PdfXConformanceException(MessageLocalization.getComposedMessage("pdfx.conformance.can.only.be.set.before.opening.the.document", new Object[0]));
            }
            if (this.crypto != null) {
                throw new PdfXConformanceException(MessageLocalization.getComposedMessage("a.pdfx.conforming.document.cannot.be.encrypted", new Object[0]));
            }
            if (pdfx != 0) {
                setPdfVersion(VERSION_1_3);
            }
            ((PdfXConformance) this.pdfIsoConformance).setPDFXConformance(pdfx);
        }
    }

    public int getPDFXConformance() {
        if (this.pdfIsoConformance instanceof PdfXConformanceImp) {
            return ((PdfXConformance) this.pdfIsoConformance).getPDFXConformance();
        }
        return 0;
    }

    public boolean isPdfX() {
        if (this.pdfIsoConformance instanceof PdfXConformanceImp) {
            return ((PdfXConformance) this.pdfIsoConformance).isPdfX();
        }
        return false;
    }

    public boolean isPdfIso() {
        return this.pdfIsoConformance.isPdfIso();
    }

    public void setOutputIntents(String outputConditionIdentifier, String outputCondition, String registryName, String info, ICC_Profile colorProfile) throws IOException {
        checkPdfIsoConformance(this, 19, colorProfile);
        getExtraCatalog();
        PdfDictionary out = new PdfDictionary(PdfName.OUTPUTINTENT);
        if (outputCondition != null) {
            out.put(PdfName.OUTPUTCONDITION, new PdfString(outputCondition, PdfObject.TEXT_UNICODE));
        }
        if (outputConditionIdentifier != null) {
            out.put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString(outputConditionIdentifier, PdfObject.TEXT_UNICODE));
        }
        if (registryName != null) {
            out.put(PdfName.REGISTRYNAME, new PdfString(registryName, PdfObject.TEXT_UNICODE));
        }
        if (info != null) {
            out.put(PdfName.INFO, new PdfString(info, PdfObject.TEXT_UNICODE));
        }
        if (colorProfile != null) {
            PdfStream stream = new PdfICCBased(colorProfile, this.compressionLevel);
            out.put(PdfName.DESTOUTPUTPROFILE, addToBody(stream).getIndirectReference());
        }
        out.put(PdfName.S, PdfName.GTS_PDFX);
        this.extraCatalog.put(PdfName.OUTPUTINTENTS, new PdfArray(out));
        this.colorProfile = colorProfile;
    }

    public void setOutputIntents(String outputConditionIdentifier, String outputCondition, String registryName, String info, byte[] destOutputProfile) throws IOException {
        ICC_Profile colorProfile = destOutputProfile == null ? null : ICC_Profile.getInstance(destOutputProfile);
        setOutputIntents(outputConditionIdentifier, outputCondition, registryName, info, colorProfile);
    }

    public boolean setOutputIntents(PdfReader reader, boolean checkExistence) throws IOException {
        PdfDictionary catalog = reader.getCatalog();
        PdfArray outs = catalog.getAsArray(PdfName.OUTPUTINTENTS);
        if (outs == null || outs.isEmpty()) {
            return false;
        }
        PdfDictionary out = outs.getAsDict(0);
        PdfObject obj = PdfReader.getPdfObject(out.get(PdfName.S));
        if (obj == null || !PdfName.GTS_PDFX.equals(obj)) {
            return false;
        }
        if (checkExistence) {
            return true;
        }
        PRStream stream = (PRStream) PdfReader.getPdfObject(out.get(PdfName.DESTOUTPUTPROFILE));
        byte[] destProfile = null;
        if (stream != null) {
            destProfile = PdfReader.getStreamBytes(stream);
        }
        setOutputIntents(getNameString(out, PdfName.OUTPUTCONDITIONIDENTIFIER), getNameString(out, PdfName.OUTPUTCONDITION), getNameString(out, PdfName.REGISTRYNAME), getNameString(out, PdfName.INFO), destProfile);
        return true;
    }

    private static String getNameString(PdfDictionary dic, PdfName key) {
        PdfObject obj = PdfReader.getPdfObject(dic.get(key));
        if (obj == null || !obj.isString()) {
            return null;
        }
        return ((PdfString) obj).toUnicodeString();
    }

    public PdfEncryption getEncryption() {
        return this.crypto;
    }

    @Override
    public void setEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, int encryptionType) throws DocumentException {
        if (this.pdf.isOpen()) {
            throw new DocumentException(MessageLocalization.getComposedMessage("encryption.can.only.be.added.before.opening.the.document", new Object[0]));
        }
        this.crypto = new PdfEncryption();
        this.crypto.setCryptoMode(encryptionType, 0);
        this.crypto.setupAllKeys(userPassword, ownerPassword, permissions);
    }

    @Override
    public void setEncryption(Certificate[] certs, int[] permissions, int encryptionType) throws DocumentException {
        if (this.pdf.isOpen()) {
            throw new DocumentException(MessageLocalization.getComposedMessage("encryption.can.only.be.added.before.opening.the.document", new Object[0]));
        }
        this.crypto = new PdfEncryption();
        if (certs != null) {
            for (int i = 0; i < certs.length; i++) {
                this.crypto.addRecipient(certs[i], permissions[i]);
            }
        }
        this.crypto.setCryptoMode(encryptionType, 0);
        this.crypto.getEncryptionDictionary();
    }

    @Deprecated
    public void setEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, boolean strength128Bits) throws DocumentException {
        setEncryption(userPassword, ownerPassword, permissions, strength128Bits ? 1 : 0);
    }

    @Deprecated
    public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException {
        setEncryption(getISOBytes(userPassword), getISOBytes(ownerPassword), permissions, strength ? 1 : 0);
    }

    @Deprecated
    public void setEncryption(int encryptionType, String userPassword, String ownerPassword, int permissions) throws DocumentException {
        setEncryption(getISOBytes(userPassword), getISOBytes(ownerPassword), permissions, encryptionType);
    }

    public boolean isFullCompression() {
        return this.fullCompression;
    }

    public void setFullCompression() throws DocumentException {
        if (this.open) {
            throw new DocumentException(MessageLocalization.getComposedMessage("you.can.t.set.the.full.compression.if.the.document.is.already.open", new Object[0]));
        }
        this.fullCompression = true;
        setAtLeastPdfVersion(VERSION_1_5);
    }

    public int getCompressionLevel() {
        return this.compressionLevel;
    }

    public void setCompressionLevel(int compressionLevel) {
        if (compressionLevel < 0 || compressionLevel > 9) {
            this.compressionLevel = -1;
        } else {
            this.compressionLevel = compressionLevel;
        }
    }

    public FontDetails addSimple(BaseFont bf) {
        FontDetails ret = this.documentFonts.get(bf);
        if (ret == null) {
            checkPdfIsoConformance(this, 4, bf);
            if (bf.getFontType() == 4) {
                StringBuilder append = new StringBuilder().append("F");
                int i = this.fontNumber;
                this.fontNumber = i + 1;
                ret = new FontDetails(new PdfName(append.append(i).toString()), ((DocumentFont) bf).getIndirectReference(), bf);
            } else {
                StringBuilder append2 = new StringBuilder().append("F");
                int i2 = this.fontNumber;
                this.fontNumber = i2 + 1;
                ret = new FontDetails(new PdfName(append2.append(i2).toString()), this.body.getPdfIndirectReference(), bf);
            }
            this.documentFonts.put(bf, ret);
        }
        return ret;
    }

    public void eliminateFontSubset(PdfDictionary fonts) {
        for (FontDetails element : this.documentFonts.values()) {
            FontDetails ft = element;
            if (fonts.get(ft.getFontName()) != null) {
                ft.setSubset(false);
            }
        }
    }

    public PdfName addDirectTemplateSimple(PdfTemplate template, PdfName forcedName) {
        PdfName name;
        PdfIndirectReference ref = template.getIndirectReference();
        Object[] obj = this.formXObjects.get(ref);
        try {
            if (obj == null) {
                if (forcedName == null) {
                    PdfName name2 = new PdfName("Xf" + this.formXObjectsCounter);
                    try {
                        this.formXObjectsCounter++;
                        name = name2;
                    } catch (Exception e) {
                        e = e;
                        throw new ExceptionConverter(e);
                    }
                } else {
                    name = forcedName;
                }
                if (template.getType() == 2) {
                    PdfImportedPage ip = (PdfImportedPage) template;
                    PdfReader r = ip.getPdfReaderInstance().getReader();
                    if (!this.readerInstances.containsKey(r)) {
                        this.readerInstances.put(r, ip.getPdfReaderInstance());
                    }
                    template = null;
                }
                this.formXObjects.put(ref, new Object[]{name, template});
                return name;
            }
            PdfName name3 = (PdfName) obj[0];
            return name3;
        } catch (Exception e2) {
            e = e2;
        }
    }

    public void releaseTemplate(PdfTemplate tp) throws IOException {
        PdfIndirectReference ref = tp.getIndirectReference();
        Object[] objs = this.formXObjects.get(ref);
        if (objs != null && objs[1] != null) {
            PdfTemplate template = (PdfTemplate) objs[1];
            if (!(template.getIndirectReference() instanceof PRIndirectReference) && template.getType() == 1) {
                addToBody(template.getFormXObject(this.compressionLevel), template.getIndirectReference());
                objs[1] = null;
            }
        }
    }

    public PdfImportedPage getImportedPage(PdfReader reader, int pageNumber) {
        return getPdfReaderInstance(reader).getImportedPage(pageNumber);
    }

    public PdfReaderInstance getPdfReaderInstance(PdfReader reader) {
        PdfReaderInstance inst = this.readerInstances.get(reader);
        if (inst == null) {
            PdfReaderInstance inst2 = reader.getPdfReaderInstance(this);
            this.readerInstances.put(reader, inst2);
            return inst2;
        }
        return inst;
    }

    public void freeReader(PdfReader reader) throws IOException {
        this.currentPdfReaderInstance = this.readerInstances.get(reader);
        if (this.currentPdfReaderInstance != null) {
            this.currentPdfReaderInstance.writeAllPages();
            this.currentPdfReaderInstance = null;
            this.readerInstances.remove(reader);
        }
    }

    public long getCurrentDocumentSize() {
        return this.body.offset() + (this.body.size() * 20) + 72;
    }

    public int getNewObjectNumber(PdfReader reader, int number, int generation) {
        if (this.currentPdfReaderInstance == null) {
            this.currentPdfReaderInstance = getPdfReaderInstance(reader);
        }
        return this.currentPdfReaderInstance.getNewObjectNumber(number, generation);
    }

    RandomAccessFileOrArray getReaderFile(PdfReader reader) {
        return this.currentPdfReaderInstance.getReaderFile();
    }

    public PdfName getColorspaceName() {
        StringBuilder append = new StringBuilder().append("CS");
        int i = this.colorNumber;
        this.colorNumber = i + 1;
        return new PdfName(append.append(i).toString());
    }

    public ColorDetails addSimple(ICachedColorSpace spc) {
        ColorDetails ret = this.documentColors.get(spc);
        if (ret == null) {
            ret = new ColorDetails(getColorspaceName(), this.body.getPdfIndirectReference(), spc);
            if (spc instanceof IPdfSpecialColorSpace) {
                ((IPdfSpecialColorSpace) spc).getColorantDetails(this);
            }
            this.documentColors.put(spc, ret);
        }
        return ret;
    }

    public PdfName addSimplePattern(PdfPatternPainter painter) {
        PdfName name = this.documentPatterns.get(painter);
        if (name == null) {
            try {
                PdfName name2 = new PdfName("P" + this.patternNumber);
                try {
                    this.patternNumber++;
                    this.documentPatterns.put(painter, name2);
                    return name2;
                } catch (Exception e) {
                    e = e;
                    throw new ExceptionConverter(e);
                }
            } catch (Exception e2) {
                e = e2;
            }
        } else {
            return name;
        }
    }

    public void addSimpleShadingPattern(PdfShadingPattern shading) {
        if (!this.documentShadingPatterns.contains(shading)) {
            shading.setName(this.patternNumber);
            this.patternNumber++;
            this.documentShadingPatterns.add(shading);
            addSimpleShading(shading.getShading());
        }
    }

    public void addSimpleShading(PdfShading shading) {
        if (!this.documentShadings.contains(shading)) {
            this.documentShadings.add(shading);
            shading.setName(this.documentShadings.size());
        }
    }

    public PdfObject[] addSimpleExtGState(PdfDictionary gstate) {
        if (!this.documentExtGState.containsKey(gstate)) {
            this.documentExtGState.put(gstate, new PdfObject[]{new PdfName("GS" + (this.documentExtGState.size() + 1)), getPdfIndirectReference()});
        }
        return this.documentExtGState.get(gstate);
    }

    public PdfObject[] addSimpleProperty(Object prop, PdfIndirectReference refi) {
        if (!this.documentProperties.containsKey(prop)) {
            if (prop instanceof PdfOCG) {
                checkPdfIsoConformance(this, 7, prop);
            }
            this.documentProperties.put(prop, new PdfObject[]{new PdfName("Pr" + (this.documentProperties.size() + 1)), refi});
        }
        return this.documentProperties.get(prop);
    }

    public boolean propertyExists(Object prop) {
        return this.documentProperties.containsKey(prop);
    }

    public void setTagged() {
        setTagged(1);
    }

    public void setTagged(int taggingMode) {
        if (this.open) {
            throw new IllegalArgumentException(MessageLocalization.getComposedMessage("tagging.must.be.set.before.opening.the.document", new Object[0]));
        }
        this.tagged = true;
        this.taggingMode = taggingMode;
    }

    public boolean needToBeMarkedInContent(IAccessibleElement element) {
        return (this.taggingMode & 1) == 0 || element.isInline() || PdfName.ARTIFACT.equals(element.getRole());
    }

    public void checkElementRole(IAccessibleElement element, IAccessibleElement parent) {
        if (parent != null && (parent.getRole() == null || PdfName.ARTIFACT.equals(parent.getRole()))) {
            element.setRole(null);
        } else if ((this.taggingMode & 1) != 0 && element.isInline() && element.getRole() == null) {
            if (parent == null || !parent.isInline()) {
                throw new IllegalArgumentException(MessageLocalization.getComposedMessage("inline.elements.with.role.null.are.not.allowed", new Object[0]));
            }
        }
    }

    public boolean isTagged() {
        return this.tagged;
    }

    public void flushTaggedObjects() throws IOException {
    }

    public void flushAcroFields() throws IOException, BadPdfFormatException {
    }

    public PdfStructureTreeRoot getStructureTreeRoot() {
        if (this.tagged && this.structureTreeRoot == null) {
            this.structureTreeRoot = new PdfStructureTreeRoot(this);
        }
        return this.structureTreeRoot;
    }

    public PdfOCProperties getOCProperties() {
        fillOCProperties(true);
        return this.OCProperties;
    }

    public void addOCGRadioGroup(ArrayList<PdfLayer> group) {
        PdfArray ar = new PdfArray();
        for (int k = 0; k < group.size(); k++) {
            PdfLayer layer = group.get(k);
            if (layer.getTitle() == null) {
                ar.add(layer.getRef());
            }
        }
        if (ar.size() != 0) {
            this.OCGRadioGroup.add(ar);
        }
    }

    public void lockLayer(PdfLayer layer) {
        this.OCGLocked.add(layer.getRef());
    }

    private static void getOCGOrder(PdfArray order, PdfLayer layer) {
        if (layer.isOnPanel()) {
            if (layer.getTitle() == null) {
                order.add(layer.getRef());
            }
            ArrayList<PdfLayer> children = layer.getChildren();
            if (children != null) {
                PdfArray kids = new PdfArray();
                if (layer.getTitle() != null) {
                    kids.add(new PdfString(layer.getTitle(), PdfObject.TEXT_UNICODE));
                }
                for (int k = 0; k < children.size(); k++) {
                    getOCGOrder(kids, children.get(k));
                }
                if (kids.size() > 0) {
                    order.add(kids);
                }
            }
        }
    }

    private void addASEvent(PdfName event, PdfName category) {
        PdfArray arr = new PdfArray();
        Iterator i$ = this.documentOCG.iterator();
        while (i$.hasNext()) {
            PdfOCG element = i$.next();
            PdfLayer layer = (PdfLayer) element;
            PdfDictionary usage = layer.getAsDict(PdfName.USAGE);
            if (usage != null && usage.get(category) != null) {
                arr.add(layer.getRef());
            }
        }
        if (arr.size() != 0) {
            PdfDictionary d = this.OCProperties.getAsDict(PdfName.D);
            PdfArray arras = d.getAsArray(PdfName.AS);
            if (arras == null) {
                arras = new PdfArray();
                d.put(PdfName.AS, arras);
            }
            PdfDictionary as = new PdfDictionary();
            as.put(PdfName.EVENT, event);
            as.put(PdfName.CATEGORY, new PdfArray(category));
            as.put(PdfName.OCGS, arr);
            arras.add(as);
        }
    }

    public void fillOCProperties(boolean erase) {
        if (this.OCProperties == null) {
            this.OCProperties = new PdfOCProperties();
        }
        if (erase) {
            this.OCProperties.remove(PdfName.OCGS);
            this.OCProperties.remove(PdfName.D);
        }
        if (this.OCProperties.get(PdfName.OCGS) == null) {
            PdfArray gr = new PdfArray();
            Iterator i$ = this.documentOCG.iterator();
            while (i$.hasNext()) {
                PdfOCG element = i$.next();
                gr.add(((PdfLayer) element).getRef());
            }
            this.OCProperties.put(PdfName.OCGS, gr);
        }
        if (this.OCProperties.get(PdfName.D) == null) {
            ArrayList<PdfOCG> docOrder = new ArrayList<>(this.documentOCGorder);
            Iterator<PdfOCG> it = docOrder.iterator();
            while (it.hasNext()) {
                if (((PdfLayer) it.next()).getParent() != null) {
                    it.remove();
                }
            }
            PdfArray order = new PdfArray();
            Iterator i$2 = docOrder.iterator();
            while (i$2.hasNext()) {
                PdfOCG element2 = i$2.next();
                getOCGOrder(order, (PdfLayer) element2);
            }
            PdfDictionary d = new PdfDictionary();
            this.OCProperties.put(PdfName.D, d);
            d.put(PdfName.ORDER, order);
            if (docOrder.size() > 0 && (docOrder.get(0) instanceof PdfLayer)) {
                PdfLayer l = (PdfLayer) docOrder.get(0);
                PdfString name = l.getAsString(PdfName.NAME);
                if (name != null) {
                    d.put(PdfName.NAME, name);
                }
            }
            PdfArray gr2 = new PdfArray();
            Iterator i$3 = this.documentOCG.iterator();
            while (i$3.hasNext()) {
                PdfOCG element3 = i$3.next();
                PdfLayer layer = (PdfLayer) element3;
                if (!layer.isOn()) {
                    gr2.add(layer.getRef());
                }
            }
            if (gr2.size() > 0) {
                d.put(PdfName.OFF, gr2);
            }
            if (this.OCGRadioGroup.size() > 0) {
                d.put(PdfName.RBGROUPS, this.OCGRadioGroup);
            }
            if (this.OCGLocked.size() > 0) {
                d.put(PdfName.LOCKED, this.OCGLocked);
            }
            addASEvent(PdfName.VIEW, PdfName.ZOOM);
            addASEvent(PdfName.VIEW, PdfName.VIEW);
            addASEvent(PdfName.PRINT, PdfName.PRINT);
            addASEvent(PdfName.EXPORT, PdfName.EXPORT);
            d.put(PdfName.LISTMODE, PdfName.VISIBLEPAGES);
        }
    }

    public void registerLayer(PdfOCG layer) {
        checkPdfIsoConformance(this, 7, layer);
        if (layer instanceof PdfLayer) {
            PdfLayer la = (PdfLayer) layer;
            if (la.getTitle() == null) {
                if (!this.documentOCG.contains(layer)) {
                    this.documentOCG.add(layer);
                    this.documentOCGorder.add(layer);
                    return;
                }
                return;
            }
            this.documentOCGorder.add(layer);
            return;
        }
        throw new IllegalArgumentException(MessageLocalization.getComposedMessage("only.pdflayer.is.accepted", new Object[0]));
    }

    public Rectangle getPageSize() {
        return this.pdf.getPageSize();
    }

    public void setCropBoxSize(Rectangle crop) {
        this.pdf.setCropBoxSize(crop);
    }

    public void setBoxSize(String boxName, Rectangle size) {
        this.pdf.setBoxSize(boxName, size);
    }

    public Rectangle getBoxSize(String boxName) {
        return this.pdf.getBoxSize(boxName);
    }

    public Rectangle getBoxSize(String boxName, Rectangle intersectingRectangle) {
        Rectangle pdfRectangle = this.pdf.getBoxSize(boxName);
        if (pdfRectangle == null || intersectingRectangle == null) {
            return null;
        }
        com.itextpdf.awt.geom.Rectangle boxRect = new com.itextpdf.awt.geom.Rectangle(pdfRectangle);
        com.itextpdf.awt.geom.Rectangle intRect = new com.itextpdf.awt.geom.Rectangle(intersectingRectangle);
        com.itextpdf.awt.geom.Rectangle outRect = boxRect.intersection(intRect);
        if (outRect.isEmpty()) {
            return null;
        }
        Rectangle output = new Rectangle((float) outRect.getX(), (float) outRect.getY(), (float) (outRect.getX() + outRect.getWidth()), (float) (outRect.getY() + outRect.getHeight()));
        output.normalize();
        return output;
    }

    public void setPageEmpty(boolean pageEmpty) {
        if (!pageEmpty) {
            this.pdf.setPageEmpty(pageEmpty);
        }
    }

    public boolean isPageEmpty() {
        return this.pdf.isPageEmpty();
    }

    public void setPageAction(PdfName actionType, PdfAction action) throws DocumentException {
        if (!actionType.equals(PAGE_OPEN) && !actionType.equals(PAGE_CLOSE)) {
            throw new DocumentException(MessageLocalization.getComposedMessage("invalid.page.additional.action.type.1", actionType.toString()));
        }
        this.pdf.setPageAction(actionType, action);
    }

    public void setDuration(int seconds) {
        this.pdf.setDuration(seconds);
    }

    public void setTransition(PdfTransition transition) {
        this.pdf.setTransition(transition);
    }

    public void setThumbnail(Image image) throws PdfException, DocumentException {
        this.pdf.setThumbnail(image);
    }

    public PdfDictionary getGroup() {
        return this.group;
    }

    public void setGroup(PdfDictionary group) {
        this.group = group;
    }

    public float getSpaceCharRatio() {
        return this.spaceCharRatio;
    }

    public void setSpaceCharRatio(float spaceCharRatio) {
        if (spaceCharRatio < 0.001f) {
            this.spaceCharRatio = 0.001f;
        } else {
            this.spaceCharRatio = spaceCharRatio;
        }
    }

    @Override
    public void setRunDirection(int runDirection) {
        if (runDirection < 1 || runDirection > 3) {
            throw new RuntimeException(MessageLocalization.getComposedMessage("invalid.run.direction.1", runDirection));
        }
        this.runDirection = runDirection;
    }

    @Override
    public int getRunDirection() {
        return this.runDirection;
    }

    public void setUserunit(float userunit) throws DocumentException {
        if (userunit < 1.0f || userunit > 75000.0f) {
            throw new DocumentException(MessageLocalization.getComposedMessage("userunit.should.be.a.value.between.1.and.75000", new Object[0]));
        }
        addPageDictEntry(PdfName.USERUNIT, new PdfNumber(userunit));
        setAtLeastPdfVersion(VERSION_1_6);
    }

    public PdfDictionary getDefaultColorspace() {
        return this.defaultColorspace;
    }

    public void setDefaultColorspace(PdfName key, PdfObject cs) {
        if (cs == null || cs.isNull()) {
            this.defaultColorspace.remove(key);
        }
        this.defaultColorspace.put(key, cs);
    }

    public ColorDetails addSimplePatternColorspace(BaseColor color) {
        int type = ExtendedColor.getType(color);
        if (type == 4 || type == 5) {
            throw new RuntimeException(MessageLocalization.getComposedMessage("an.uncolored.tile.pattern.can.not.have.another.pattern.or.shading.as.color", new Object[0]));
        }
        try {
            switch (type) {
                case 0:
                    if (this.patternColorspaceRGB == null) {
                        this.patternColorspaceRGB = new ColorDetails(getColorspaceName(), this.body.getPdfIndirectReference(), null);
                        PdfArray array = new PdfArray(PdfName.PATTERN);
                        array.add(PdfName.DEVICERGB);
                        addToBody(array, this.patternColorspaceRGB.getIndirectReference());
                    }
                    return this.patternColorspaceRGB;
                case 1:
                    if (this.patternColorspaceGRAY == null) {
                        this.patternColorspaceGRAY = new ColorDetails(getColorspaceName(), this.body.getPdfIndirectReference(), null);
                        PdfArray array2 = new PdfArray(PdfName.PATTERN);
                        array2.add(PdfName.DEVICEGRAY);
                        addToBody(array2, this.patternColorspaceGRAY.getIndirectReference());
                    }
                    return this.patternColorspaceGRAY;
                case 2:
                    if (this.patternColorspaceCMYK == null) {
                        this.patternColorspaceCMYK = new ColorDetails(getColorspaceName(), this.body.getPdfIndirectReference(), null);
                        PdfArray array3 = new PdfArray(PdfName.PATTERN);
                        array3.add(PdfName.DEVICECMYK);
                        addToBody(array3, this.patternColorspaceCMYK.getIndirectReference());
                    }
                    return this.patternColorspaceCMYK;
                case 3:
                    ColorDetails details = addSimple(((SpotColor) color).getPdfSpotColor());
                    ColorDetails patternDetails = this.documentSpotPatterns.get(details);
                    if (patternDetails == null) {
                        ColorDetails patternDetails2 = new ColorDetails(getColorspaceName(), this.body.getPdfIndirectReference(), null);
                        PdfArray array4 = new PdfArray(PdfName.PATTERN);
                        array4.add(details.getIndirectReference());
                        addToBody(array4, patternDetails2.getIndirectReference());
                        this.documentSpotPatterns.put(details, patternDetails2);
                        return patternDetails2;
                    }
                    return patternDetails;
                default:
                    throw new RuntimeException(MessageLocalization.getComposedMessage("invalid.color.type", new Object[0]));
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    public boolean isStrictImageSequence() {
        return this.pdf.isStrictImageSequence();
    }

    public void setStrictImageSequence(boolean strictImageSequence) {
        this.pdf.setStrictImageSequence(strictImageSequence);
    }

    public void clearTextWrap() throws DocumentException {
        this.pdf.clearTextWrap();
    }

    public PdfName addDirectImageSimple(Image image) throws PdfException, DocumentException {
        return addDirectImageSimple(image, null);
    }

    public PdfName addDirectImageSimple(Image image, PdfIndirectReference fixedRef) throws PdfException, DocumentException {
        PdfName name;
        byte[] globals;
        if (this.images.containsKey(image.getMySerialId())) {
            name = this.images.get(image.getMySerialId());
        } else {
            if (image.isImgTemplate()) {
                name = new PdfName(HtmlTags.IMG + this.images.size());
                if (image instanceof ImgWMF) {
                    try {
                        ImgWMF wmf = (ImgWMF) image;
                        wmf.readWMF(PdfTemplate.createTemplate(this, 0.0f, 0.0f));
                    } catch (Exception e) {
                        throw new DocumentException(e);
                    }
                }
            } else {
                PdfIndirectReference dref = image.getDirectReference();
                if (dref != null) {
                    PdfName rname = new PdfName(HtmlTags.IMG + this.images.size());
                    this.images.put(image.getMySerialId(), rname);
                    this.imageDictionary.put(rname, dref);
                    return rname;
                }
                Image maskImage = image.getImageMask();
                PdfIndirectReference maskRef = null;
                if (maskImage != null) {
                    PdfName mname = this.images.get(maskImage.getMySerialId());
                    maskRef = getImageReference(mname);
                }
                PdfImage i = new PdfImage(image, HtmlTags.IMG + this.images.size(), maskRef);
                if ((image instanceof ImgJBIG2) && (globals = ((ImgJBIG2) image).getGlobalBytes()) != null) {
                    PdfDictionary decodeparms = new PdfDictionary();
                    decodeparms.put(PdfName.JBIG2GLOBALS, getReferenceJBIG2Globals(globals));
                    i.put(PdfName.DECODEPARMS, decodeparms);
                }
                if (image.hasICCProfile()) {
                    PdfICCBased icc = new PdfICCBased(image.getICCProfile(), image.getCompressionLevel());
                    PdfIndirectReference iccRef = add(icc);
                    PdfArray iccArray = new PdfArray();
                    iccArray.add(PdfName.ICCBASED);
                    iccArray.add(iccRef);
                    PdfArray colorspace = i.getAsArray(PdfName.COLORSPACE);
                    if (colorspace != null) {
                        if (colorspace.size() > 1 && PdfName.INDEXED.equals(colorspace.getPdfObject(0))) {
                            colorspace.set(1, iccArray);
                        } else {
                            i.put(PdfName.COLORSPACE, iccArray);
                        }
                    } else {
                        i.put(PdfName.COLORSPACE, iccArray);
                    }
                }
                add(i, fixedRef);
                name = i.name();
            }
            this.images.put(image.getMySerialId(), name);
        }
        return name;
    }

    PdfIndirectReference add(PdfImage pdfImage, PdfIndirectReference fixedRef) throws PdfException {
        if (!this.imageDictionary.contains(pdfImage.name())) {
            checkPdfIsoConformance(this, 5, pdfImage);
            if (fixedRef instanceof PRIndirectReference) {
                PRIndirectReference r2 = (PRIndirectReference) fixedRef;
                fixedRef = new PdfIndirectReference(0, getNewObjectNumber(r2.getReader(), r2.getNumber(), r2.getGeneration()));
            }
            try {
                if (fixedRef == null) {
                    fixedRef = addToBody(pdfImage).getIndirectReference();
                } else {
                    addToBody(pdfImage, fixedRef);
                }
                this.imageDictionary.put(pdfImage.name(), fixedRef);
                return fixedRef;
            } catch (IOException ioe) {
                throw new ExceptionConverter(ioe);
            }
        }
        return (PdfIndirectReference) this.imageDictionary.get(pdfImage.name());
    }

    public PdfIndirectReference getImageReference(PdfName name) {
        return (PdfIndirectReference) this.imageDictionary.get(name);
    }

    protected PdfIndirectReference add(PdfICCBased icc) {
        try {
            PdfIndirectObject object = addToBody(icc);
            return object.getIndirectReference();
        } catch (IOException ioe) {
            throw new ExceptionConverter(ioe);
        }
    }

    public PdfIndirectReference getReferenceJBIG2Globals(byte[] content) {
        if (content == null) {
            return null;
        }
        for (PdfStream stream : this.JBIG2Globals.keySet()) {
            if (Arrays.equals(content, stream.getBytes())) {
                return this.JBIG2Globals.get(stream);
            }
        }
        PdfStream stream2 = new PdfStream(content);
        try {
            PdfIndirectObject ref = addToBody(stream2);
            this.JBIG2Globals.put(stream2, ref.getIndirectReference());
            return ref.getIndirectReference();
        } catch (IOException e) {
            return null;
        }
    }

    public boolean isUserProperties() {
        return this.userProperties;
    }

    public void setUserProperties(boolean userProperties) {
        this.userProperties = userProperties;
    }

    public boolean isRgbTransparencyBlending() {
        return this.rgbTransparencyBlending;
    }

    public void setRgbTransparencyBlending(boolean rgbTransparencyBlending) {
        this.rgbTransparencyBlending = rgbTransparencyBlending;
    }

    public static void writeKeyInfo(OutputStream os) throws IOException {
        Version version = Version.getInstance();
        String k = version.getKey();
        if (k == null) {
            k = "iText";
        }
        os.write(getISOBytes(String.format("%%%s-%s\n", k, version.getRelease())));
    }

    public TtfUnicodeWriter getTtfUnicodeWriter() {
        if (this.ttfUnicodeWriter == null) {
            this.ttfUnicodeWriter = new TtfUnicodeWriter(this);
        }
        return this.ttfUnicodeWriter;
    }

    public XmpWriter createXmpWriter(ByteArrayOutputStream baos, PdfDictionary info) throws IOException {
        return new XmpWriter(baos, info);
    }

    public XmpWriter createXmpWriter(ByteArrayOutputStream baos, HashMap<String, String> info) throws IOException {
        return new XmpWriter(baos, info);
    }

    public static void checkPdfIsoConformance(PdfWriter writer, int key, Object obj1) {
        if (writer != null) {
            writer.checkPdfIsoConformance(key, obj1);
        }
    }

    public void checkPdfIsoConformance(int key, Object obj1) {
        this.pdfIsoConformance.checkPdfIsoConformance(key, obj1);
    }

    private void completeInfoDictionary(PdfDictionary info) {
        if (isPdfX()) {
            if (info.get(PdfName.GTS_PDFXVERSION) == null) {
                if (((PdfXConformanceImp) this.pdfIsoConformance).isPdfX1A2001()) {
                    info.put(PdfName.GTS_PDFXVERSION, new PdfString("PDF/X-1:2001"));
                    info.put(new PdfName("GTS_PDFXConformance"), new PdfString("PDF/X-1a:2001"));
                } else if (((PdfXConformanceImp) this.pdfIsoConformance).isPdfX32002()) {
                    info.put(PdfName.GTS_PDFXVERSION, new PdfString("PDF/X-3:2002"));
                }
            }
            if (info.get(PdfName.TITLE) == null) {
                info.put(PdfName.TITLE, new PdfString("Pdf document"));
            }
            if (info.get(PdfName.CREATOR) == null) {
                info.put(PdfName.CREATOR, new PdfString("Unknown"));
            }
            if (info.get(PdfName.TRAPPED) == null) {
                info.put(PdfName.TRAPPED, new PdfName(XMPConst.FALSESTR));
            }
        }
    }

    private void completeExtraCatalog(PdfDictionary extraCatalog) {
        if (isPdfX() && extraCatalog.get(PdfName.OUTPUTINTENTS) == null) {
            PdfDictionary out = new PdfDictionary(PdfName.OUTPUTINTENT);
            out.put(PdfName.OUTPUTCONDITION, new PdfString("SWOP CGATS TR 001-1995"));
            out.put(PdfName.OUTPUTCONDITIONIDENTIFIER, new PdfString("CGATS TR 001"));
            out.put(PdfName.REGISTRYNAME, new PdfString("http://www.color.org"));
            out.put(PdfName.INFO, new PdfString(PdfObject.NOTHING));
            out.put(PdfName.S, PdfName.GTS_PDFX);
            extraCatalog.put(PdfName.OUTPUTINTENTS, new PdfArray(out));
        }
    }

    public List<PdfName> getStandardStructElems() {
        return this.pdf_version.getVersion() < '7' ? standardStructElems_1_4 : standardStructElems_1_7;
    }
}