private static String GetCOName(PdfReader reader, PRIndirectReference refi) { String name = ""; while (refi != null) { PdfObject obj = PdfReader.GetPdfObject(refi); if (obj == null || obj.Type != PdfObject.DICTIONARY) { break; } PdfDictionary dic = (PdfDictionary)obj; PdfString t = dic.GetAsString(PdfName.T); if (t != null) { name = t.ToUnicodeString() + "." + name; } refi = (PRIndirectReference)dic.Get(PdfName.PARENT); } if (name.EndsWith(".")) { name = name.Substring(0, name.Length - 1); } return(name); }
/** * Add an imported page to our output * @param iPage an imported page * @throws IOException, BadPdfFormatException */ public void AddPage(PdfImportedPage iPage) { int pageNum = SetFromIPage(iPage); PdfDictionary thePage = reader.GetPageN(pageNum); PRIndirectReference origRef = reader.GetPageOrigRef(pageNum); reader.ReleasePage(pageNum); RefKey key = new RefKey(origRef); PdfIndirectReference pageRef; IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null && !iRef.Copied) { pageReferences.Add(iRef.Ref); iRef.SetCopied(); } pageRef = CurrentPage; if (iRef == null) { iRef = new IndirectReferences(pageRef); indirects[key] = iRef; } iRef.SetCopied(); PdfDictionary newPage = CopyDictionary(thePage); root.AddPage(newPage); iPage.SetCopied(); ++currentPageNumber; }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected virtual PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef = (IndirectReferences)indirects[key]; if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return(theRef); } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } PdfObject obj = PdfReader.GetPdfObjectRelease(inp); if (obj != null && obj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return(theRef); } } iRef.SetCopied(); obj = CopyObject(obj); AddToBody(obj, theRef); return(theRef); }
private static void DeleteOldReferences(PdfArray all, PdfArray toDelete) { if (all == null || toDelete == null) { return; } foreach (PdfObject pi in toDelete) { if (!pi.IsIndirect()) { continue; } PRIndirectReference pir = (PRIndirectReference)pi; for (int k = 0; k < all.Size; ++k) { PdfObject po = all[k]; if (!po.IsIndirect()) { continue; } PRIndirectReference pod = (PRIndirectReference)po; if (pir.Number == pod.Number) { all.Remove(k); --k; } } } }
protected bool SetVisited(PRIndirectReference refi) { IntHashtable refs = (IntHashtable)visited[refi.Reader]; int old = refs[refi.Number]; refs[refi.Number] = 1; return(old != 0); }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected virtual PdfIndirectReference CopyIndirect(PRIndirectReference inp, bool keepStructure, bool directRootKids) { PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef; indirects.TryGetValue(key, out iRef); PdfObject obj = PdfReader.GetPdfObjectRelease(inp); if ((keepStructure) && (directRootKids)) { if (obj is PdfDictionary) { PdfDictionary dict = (PdfDictionary)obj; if (dict.Contains(PdfName.PG)) { return(null); } } } if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return(theRef); } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } if (obj != null && obj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return(theRef); } } iRef.SetCopied(); parentObjects[obj] = inp; PdfObject res = CopyObject(obj, keepStructure, directRootKids); if (disableIndirects.ContainsKey(obj)) { iRef.Copied = false; } if ((res != null) && !(res is PdfNull)) { AddToBody(res, theRef); return(theRef); } indirects.Remove(key); return(null); }
/** Does the actual document manipulation to encrypt it. * @throws DocumentException on error * @throws IOException on error */ protected void go() { body = new PdfBody(HEADER.Length, this, true); os.Write(HEADER, 0, HEADER.Length); PdfObject[] xb = reader.xrefObj; myXref = new int[xb.Length]; int idx = 1; for (int k = 1; k < xb.Length; ++k) { if (xb[k] != null) { myXref[k] = idx++; } } file.reOpen(); for (int k = 1; k < xb.Length; ++k) { if (xb[k] != null) { addToBody(xb[k]); } } file.close(); PdfIndirectReference encryption = null; PdfLiteral fileID = null; if (crypto != null) { PdfIndirectObject encryptionObject = body.Add(crypto.EncryptionDictionary); encryptionObject.writeTo(os); encryption = encryptionObject.IndirectReference; fileID = crypto.FileID; } // write the cross-reference table of the body os.Write(body.CrossReferenceTable, 0, body.CrossReferenceTable.Length); PRIndirectReference iRoot = (PRIndirectReference)reader.trailer.get(PdfName.ROOT); PdfIndirectReference root = new PdfIndirectReference(0, myXref[iRoot.Number]); PRIndirectReference iInfo = (PRIndirectReference)reader.trailer.get(PdfName.INFO); PdfIndirectReference info = null; if (iInfo != null) { info = new PdfIndirectReference(0, myXref[iInfo.Number]); } PdfTrailer trailer = new PdfTrailer(body.Size, body.Offset, root, info, encryption, fileID); byte[] tmp = trailer.toPdf(this); os.Write(tmp, 0, tmp.Length); os.Close(); }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file if it wasn't available * in the cache yet. If it's in the cache, the reference to * the already used stream is returned. * * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected override PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfObject srcObj = PdfReader.GetPdfObjectRelease(inp); ByteStore streamKey = null; bool validStream = false; if (srcObj.IsStream()) { streamKey = new ByteStore((PRStream)srcObj); validStream = true; PdfIndirectReference streamRef; if (streamMap.TryGetValue(streamKey, out streamRef)) { return(streamRef); } } PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return(theRef); } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } if (srcObj != null && srcObj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)srcObj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return(theRef); } } iRef.SetCopied(); if (validStream) { streamMap[streamKey] = theRef; } PdfObject obj = CopyObject(srcObj); AddToBody(obj, theRef); return(theRef); }
virtual protected void CloseIt() { for (int k = 0; k < readers.Count; ++k) { readers[k].RemoveFields(); } for (int r = 0; r < readers.Count; ++r) { PdfReader reader = readers[r]; for (int page = 1; page <= reader.NumberOfPages; ++page) { pageRefs.Add(GetNewReference(reader.GetPageOrigRef(page))); pageDics.Add(reader.GetPageN(page)); } } MergeFields(); CreateAcroForms(); for (int r = 0; r < readers.Count; ++r) { PdfReader reader = readers[r]; for (int page = 1; page <= reader.NumberOfPages; ++page) { PdfDictionary dic = reader.GetPageN(page); PdfIndirectReference pageRef = GetNewReference(reader.GetPageOrigRef(page)); PdfIndirectReference parent = root.AddPageRef(pageRef); dic.Put(PdfName.PARENT, parent); Propagate(dic, pageRef, false); } } foreach (KeyValuePair <PdfReader, IntHashtable> entry in readers2intrefs) { PdfReader reader = entry.Key; try { file = reader.SafeFile; file.ReOpen(); IntHashtable t = entry.Value; int[] keys = t.ToOrderedKeys(); for (int k = 0; k < keys.Length; ++k) { PRIndirectReference refi = new PRIndirectReference(reader, keys[k]); AddToBody(PdfReader.GetPdfObjectRelease(refi), t[keys[k]]); } } finally { try { file.Close(); // TODO: Removed - the user should be responsible for closing all PdfReaders. But, this could cause a lot of memory leaks in code out there that hasn't been properly closing things - maybe add a finalizer to PdfReader that calls PdfReader#close() ?? //reader.Close(); } catch { // empty on purpose } } } pdf.Close(); }
protected void CloseIt() { for (int k = 0; k < readers.Count; ++k) { ((PdfReader)readers[k]).RemoveFields(); } for (int r = 0; r < readers.Count; ++r) { PdfReader reader = (PdfReader)readers[r]; for (int page = 1; page <= reader.NumberOfPages; ++page) { pageRefs.Add(GetNewReference(reader.GetPageOrigRef(page))); pageDics.Add(reader.GetPageN(page)); } } MergeFields(); CreateAcroForms(); for (int r = 0; r < readers.Count; ++r) { PdfReader reader = (PdfReader)readers[r]; for (int page = 1; page <= reader.NumberOfPages; ++page) { PdfDictionary dic = reader.GetPageN(page); PdfIndirectReference pageRef = GetNewReference(reader.GetPageOrigRef(page)); PdfIndirectReference parent = root.AddPageRef(pageRef); dic.Put(PdfName.PARENT, parent); Propagate(dic, pageRef, false); } } foreach (DictionaryEntry entry in readers2intrefs) { PdfReader reader = (PdfReader)entry.Key; try { file = reader.SafeFile; file.ReOpen(); IntHashtable t = (IntHashtable)entry.Value; int[] keys = t.ToOrderedKeys(); for (int k = 0; k < keys.Length; ++k) { PRIndirectReference refi = new PRIndirectReference(reader, keys[k]); AddToBody(PdfReader.GetPdfObjectRelease(refi), t[keys[k]]); } } finally { try { file.Close(); reader.Close(); } catch { // empty on purpose } } } pdf.Close(); }
/** Creates a new instance of DocumentFont */ internal DocumentFont(PRIndirectReference refFont) { encoding = ""; fontSpecific = false; this.refFont = refFont; fontType = FONT_TYPE_DOCUMENT; font = (PdfDictionary)PdfReader.GetPdfObject(refFont); PdfName baseFont = font.GetAsName(PdfName.BASEFONT); fontName = baseFont != null?PdfName.DecodeName(baseFont.ToString()) : "Unspecified Font Name"; PdfName subType = font.GetAsName(PdfName.SUBTYPE); if (PdfName.TYPE1.Equals(subType) || PdfName.TRUETYPE.Equals(subType)) { DoType1TT(); } else { for (int k = 0; k < cjkNames.Length; ++k) { if (fontName.StartsWith(cjkNames[k])) { fontName = cjkNames[k]; cjkMirror = BaseFont.CreateFont(fontName, cjkEncs[k], false); return; } } PdfName encodingName = font.GetAsName(PdfName.ENCODING); if (encodingName != null) { String enc = PdfName.DecodeName(encodingName.ToString()); for (int k = 0; k < cjkEncs2.Length; ++k) { if (enc.StartsWith(cjkEncs2[k])) { if (k > 3) { k -= 4; } cjkMirror = BaseFont.CreateFont(cjkNames2[k], cjkEncs2[k], false); return; } } if (PdfName.TYPE0.Equals(subType) && enc.Equals("Identity-H")) { ProcessType0(font); isType0 = true; } } } }
/** * Checks if a reference refers to a page object. * @param ref the reference that needs to be checked * @return true is the reference refers to a page object. */ protected internal bool IsPage(PRIndirectReference refi) { IntHashtable refs = (IntHashtable)pages2intrefs[refi.Reader]; if (refs != null) { return(refs.ContainsKey(refi.Number)); } else { return(false); } }
/** * Creates an instance of a CMapAwareFont based on an indirect reference to a font. * @param refFont the indirect reference to a font */ public CMapAwareDocumentFont(PRIndirectReference refFont) : base(refFont){ fontDic = (PdfDictionary)PdfReader.GetPdfObjectRelease(refFont); ProcessToUnicode(); //if (toUnicodeCmap == null) ProcessUni2Byte(); spaceWidth = base.GetWidth(' '); if (spaceWidth == 0){ spaceWidth = ComputeAverageWidth(); } }
/** * Checks if a reference refers to a page object. * @param ref the reference that needs to be checked * @return true is the reference refers to a page object. */ virtual protected internal bool IsPage(PRIndirectReference refi) { IntHashtable refs; if (pages2intrefs.TryGetValue(refi.Reader, out refs)) { return(refs.ContainsKey(refi.Number)); } else { return(false); } }
/** * Checks if a reference has already been "visited" in the copy process. * @param ref the reference that needs to be checked * @return true if the reference was already visited */ protected internal bool IsVisited(PRIndirectReference refi) { IntHashtable refs; if (visited.TryGetValue(refi.Reader, out refs)) { return(refs.ContainsKey(refi.Number)); } else { return(false); } }
/** * Creates an instance of a CMapAwareFont based on an indirect reference to a font. * @param refFont the indirect reference to a font */ public CMapAwareDocumentFont(PRIndirectReference refFont) : base(refFont) { fontDic = (PdfDictionary)PdfReader.GetPdfObjectRelease(refFont); ProcessToUnicode(); //if (toUnicodeCmap == null) ProcessUni2Byte(); spaceWidth = base.GetWidth(' '); if (spaceWidth == 0) { spaceWidth = ComputeAverageWidth(); } }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file if it wasn't available * in the cache yet. If it's in the cache, the reference to * the already used stream is returned. * * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected override PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfObject srcObj = PdfReader.GetPdfObjectRelease(inp); ByteStore streamKey = null; bool validStream = false; if (srcObj.IsStream()) { streamKey = new ByteStore((PRStream)srcObj); validStream = true; PdfIndirectReference streamRef; if (streamMap.TryGetValue(streamKey, out streamRef)) { return streamRef; } } else if (srcObj.IsDictionary()) { streamKey = new ByteStore((PdfDictionary)srcObj); validStream = true; PdfIndirectReference streamRef = null; if (streamMap.TryGetValue(streamKey, out streamRef)) { return streamRef; } } PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return theRef; } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } if (srcObj != null && srcObj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)srcObj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return theRef; } } iRef.SetCopied(); if (validStream) { streamMap[streamKey] = theRef; } PdfObject obj = CopyObject(srcObj); AddToBody(obj, theRef); return theRef; }
/** * After reading, we index all of the fields. Recursive. * @param fieldlist An array of fields * @param fieldDict the last field dictionary we encountered (recursively) * @param parentPath the pathname of the field, up to this point or null */ virtual protected void IterateFields(PdfArray fieldlist, PRIndirectReference fieldDict, String parentPath) { foreach (PRIndirectReference refi in fieldlist.ArrayList) { PdfDictionary dict = (PdfDictionary)PdfReader.GetPdfObjectRelease(refi); // if we are not a field dictionary, pass our parent's values PRIndirectReference myFieldDict = fieldDict; String fullPath = parentPath; PdfString tField = (PdfString)dict.Get(PdfName.T); bool isFieldDict = tField != null; if (isFieldDict) { myFieldDict = refi; if (parentPath == null) { fullPath = tField.ToString(); } else { fullPath = parentPath + '.' + tField.ToString(); } } PdfArray kids = (PdfArray)dict.Get(PdfName.KIDS); if (kids != null) { PushAttrib(dict); IterateFields(kids, myFieldDict, fullPath); stack.RemoveAt(stack.Count - 1); // pop } else // leaf node { if (myFieldDict != null) { PdfDictionary mergedDict = (PdfDictionary)stack[stack.Count - 1]; if (isFieldDict) { mergedDict = MergeAttrib(mergedDict, dict); } mergedDict.Put(PdfName.T, new PdfString(fullPath)); FieldInformation fi = new FieldInformation(fullPath, mergedDict, myFieldDict); fields.Add(fi); fieldByName[fullPath] = fi; } } } }
/** * Sets a reference to "visited" in the copy process. * @param ref the reference that needs to be set to "visited" * @return true if the reference was set to visited */ protected internal bool SetVisited(PRIndirectReference refi) { IntHashtable refs = (IntHashtable)visited[refi.Reader]; if (refs != null) { int old = refs[refi.Number]; refs[refi.Number] = 1; return(old != 0); } else { return(false); } }
/** * Sets a reference to "visited" in the copy process. * @param ref the reference that needs to be set to "visited" * @return true if the reference was set to visited */ virtual protected internal bool SetVisited(PRIndirectReference refi) { IntHashtable refs; if (visited.TryGetValue(refi.Reader, out refs)) { int old = refs[refi.Number]; refs[refi.Number] = 1; return(old != 0); } else { return(false); } }
/** Creates a new instance of DocumentFont */ internal DocumentFont(PRIndirectReference refFont, PdfDictionary drEncoding) { this.refFont = refFont; font = (PdfDictionary)PdfReader.GetPdfObject(refFont); if (font.Get(PdfName.ENCODING) == null && drEncoding != null) { foreach (PdfName key in drEncoding.Keys) { font.Put(PdfName.ENCODING, drEncoding.Get(key)); } } Init(); }
private void AddKid(PdfObject obj) { if (!obj.IsIndirect()) { return; } PRIndirectReference currRef = (PRIndirectReference)obj; PdfCopy.RefKey key = new PdfCopy.RefKey(currRef); if (!writer.indirects.ContainsKey(key)) { writer.CopyIndirect(currRef, true, false); } PdfIndirectReference newKid = writer.indirects[key].Ref; if (writer.updateRootKids) { AddKid(structureTreeRoot, newKid); } }
/** * Copy the acroform for an input document. Note that you can only have one, * we make no effort to merge them. * @param reader The reader of the input file that is being copied * @throws IOException, BadPdfFormatException */ public void CopyAcroForm(PdfReader reader) { SetFromReader(reader); PdfDictionary catalog = reader.Catalog; PRIndirectReference hisRef = null; PdfObject o = catalog.Get(PdfName.ACROFORM); if (o != null && o.Type == PdfObject.INDIRECT) { hisRef = (PRIndirectReference)o; } if (hisRef == null) { return; // bugfix by John Engla } RefKey key = new RefKey(hisRef); PdfIndirectReference myRef; IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null) { acroForm = myRef = iRef.Ref; } else { acroForm = myRef = body.PdfIndirectReference; iRef = new IndirectReferences(myRef); indirects[key] = iRef; } if (!iRef.Copied) { iRef.SetCopied(); PdfDictionary theForm = CopyDictionary((PdfDictionary)PdfReader.GetPdfObject(hisRef)); AddToBody(theForm, myRef); } }
/** * convenience method. Given a reader, set our "globals" */ protected void SetFromReader(PdfReader reader) { this.reader = reader; indirectMap.TryGetValue(reader, out indirects); if (indirects == null) { indirects = new Dictionary <RefKey, IndirectReferences>(); indirectMap[reader] = indirects; PdfDictionary catalog = reader.Catalog; PRIndirectReference refi = null; PdfObject o = catalog.Get(PdfName.ACROFORM); if (o == null || o.Type != PdfObject.INDIRECT) { return; } refi = (PRIndirectReference)o; if (acroForm == null) { acroForm = body.PdfIndirectReference; } indirects[new RefKey(refi)] = new IndirectReferences(acroForm); } }
virtual public int GetDestinationPage() { if (!IsInternal()) { return(0); } // here destination is something like // [132 0 R, /XYZ, 29.3898, 731.864502, null] PdfIndirectReference refi = destination.GetAsIndirectObject(0); PRIndirectReference pr = (PRIndirectReference)refi; PdfReader r = pr.Reader; for (int i = 1; i <= r.NumberOfPages; i++) { PRIndirectReference pp = r.GetPageOrigRef(i); if (pp.Generation == pr.Generation && pp.Number == pr.Number) { return(i); } } throw new ArgumentException(MessageLocalization.GetComposedMessage("page.not.found")); }
internal void InsertPage(int pageNumber, Rectangle mediabox) { Rectangle media = new Rectangle(mediabox); int rotation = media.Rotation % 360; PdfDictionary page = new PdfDictionary(PdfName.PAGE); PdfDictionary resources = new PdfDictionary(); PdfArray procset = new PdfArray(); procset.Add(PdfName.PDF); procset.Add(PdfName.TEXT); procset.Add(PdfName.IMAGEB); procset.Add(PdfName.IMAGEC); procset.Add(PdfName.IMAGEI); resources.Put(PdfName.PROCSET, procset); page.Put(PdfName.RESOURCES, resources); page.Put(PdfName.ROTATE, new PdfNumber(rotation)); page.Put(PdfName.MEDIABOX, new PdfRectangle(media, rotation)); PRIndirectReference pref = reader.AddPdfObject(page); PdfDictionary parent; PRIndirectReference parentRef; if (pageNumber > reader.NumberOfPages) { PdfDictionary lastPage = reader.GetPageNRelease(reader.NumberOfPages); parentRef = (PRIndirectReference)lastPage.Get(PdfName.PARENT); parentRef = new PRIndirectReference(reader, parentRef.Number); parent = (PdfDictionary)PdfReader.GetPdfObject(parentRef); PdfArray kids = (PdfArray)PdfReader.GetPdfObject(parent.Get(PdfName.KIDS), parent); kids.Add(pref); MarkUsed(kids); reader.pageRefs.InsertPage(pageNumber, pref); } else { if (pageNumber < 1) pageNumber = 1; PdfDictionary firstPage = reader.GetPageN(pageNumber); PRIndirectReference firstPageRef = reader.GetPageOrigRef(pageNumber); reader.ReleasePage(pageNumber); parentRef = (PRIndirectReference)firstPage.Get(PdfName.PARENT); parentRef = new PRIndirectReference(reader, parentRef.Number); parent = (PdfDictionary)PdfReader.GetPdfObject(parentRef); PdfArray kids = (PdfArray)PdfReader.GetPdfObject(parent.Get(PdfName.KIDS), parent); ArrayList ar = kids.ArrayList; int len = ar.Count; int num = firstPageRef.Number; for (int k = 0; k < len; ++k) { PRIndirectReference cur = (PRIndirectReference)ar[k]; if (num == cur.Number) { ar.Insert(k, pref); break; } } if (len == ar.Count) throw new Exception("Internal inconsistence."); MarkUsed(kids); reader.pageRefs.InsertPage(pageNumber, pref); CorrectAcroFieldPages(pageNumber); } page.Put(PdfName.PARENT, parentRef); while (parent != null) { MarkUsed(parent); PdfNumber count = (PdfNumber)PdfReader.GetPdfObjectRelease(parent.Get(PdfName.COUNT)); parent.Put(PdfName.COUNT, new PdfNumber(count.IntValue + 1)); parent = (PdfDictionary)PdfReader.GetPdfObject(parent.Get(PdfName.PARENT)); } }
/** * After reading, we index all of the fields. Recursive. * @param fieldlist An array of fields * @param fieldDict the last field dictionary we encountered (recursively) * @param parentPath the pathname of the field, up to this point or null */ virtual protected void IterateFields(PdfArray fieldlist, PRIndirectReference fieldDict, String parentPath) { foreach (PRIndirectReference refi in fieldlist.ArrayList) { PdfDictionary dict = (PdfDictionary) PdfReader.GetPdfObjectRelease(refi); // if we are not a field dictionary, pass our parent's values PRIndirectReference myFieldDict = fieldDict; String fullPath = parentPath; PdfString tField = (PdfString)dict.Get(PdfName.T); bool isFieldDict = tField != null; if (isFieldDict) { myFieldDict = refi; if (parentPath == null) { fullPath = tField.ToString(); } else { fullPath = parentPath + '.' + tField.ToString(); } } PdfArray kids = (PdfArray)dict.Get(PdfName.KIDS); if (kids != null) { PushAttrib(dict); IterateFields(kids, myFieldDict, fullPath); stack.RemoveAt(stack.Count - 1); // pop } else { // leaf node if (myFieldDict != null) { PdfDictionary mergedDict = (PdfDictionary)stack[stack.Count - 1]; if (isFieldDict) mergedDict = MergeAttrib(mergedDict, dict); mergedDict.Put(PdfName.T, new PdfString(fullPath)); FieldInformation fi = new FieldInformation(fullPath, mergedDict, myFieldDict); fields.Add(fi); fieldByName[fullPath] = fi; } } } }
private static void AddFont(PRIndirectReference fontRef, IntHashtable hits, List<object[]> fonts) { PdfObject obj = PdfReader.GetPdfObject(fontRef); if (obj == null || !obj.IsDictionary()) return; PdfDictionary font = (PdfDictionary)obj; PdfName subtype = font.GetAsName(PdfName.SUBTYPE); if (!PdfName.TYPE1.Equals(subtype) && !PdfName.TRUETYPE.Equals(subtype) && !PdfName.TYPE0.Equals(subtype)) return; PdfName name = font.GetAsName(PdfName.BASEFONT); fonts.Add(new Object[]{PdfName.DecodeName(name.ToString()), fontRef}); hits[fontRef.Number] = 1; }
/** * Sets a reference to "visited" in the copy process. * @param ref the reference that needs to be set to "visited" * @return true if the reference was set to visited */ protected internal bool SetVisited(PRIndirectReference refi) { IntHashtable refs; if (visited.TryGetValue(refi.Reader, out refs)) { int old = refs[refi.Number]; refs[refi.Number] = 1; return (old != 0); } else return false; }
protected void CloseIt() { for (int k = 0; k < readers.Count; ++k) { readers[k].RemoveFields(); } for (int r = 0; r < readers.Count; ++r) { PdfReader reader = readers[r]; for (int page = 1; page <= reader.NumberOfPages; ++page) { pageRefs.Add(GetNewReference(reader.GetPageOrigRef(page))); pageDics.Add(reader.GetPageN(page)); } } MergeFields(); CreateAcroForms(); for (int r = 0; r < readers.Count; ++r) { PdfReader reader = readers[r]; for (int page = 1; page <= reader.NumberOfPages; ++page) { PdfDictionary dic = reader.GetPageN(page); PdfIndirectReference pageRef = GetNewReference(reader.GetPageOrigRef(page)); PdfIndirectReference parent = root.AddPageRef(pageRef); dic.Put(PdfName.PARENT, parent); Propagate(dic, pageRef, false); } } foreach (KeyValuePair<PdfReader, IntHashtable> entry in readers2intrefs) { PdfReader reader = entry.Key; try { file = reader.SafeFile; file.ReOpen(); IntHashtable t = entry.Value; int[] keys = t.ToOrderedKeys(); for (int k = 0; k < keys.Length; ++k) { PRIndirectReference refi = new PRIndirectReference(reader, keys[k]); AddToBody(PdfReader.GetPdfObjectRelease(refi), t[keys[k]]); } } finally { try { file.Close(); // TODO: Removed - the user should be responsible for closing all PdfReaders. But, this could cause a lot of memory leaks in code out there that hasn't been properly closing things - maybe add a finalizer to PdfReader that calls PdfReader#close() ?? //reader.Close(); } catch { // empty on purpose } } } pdf.Close(); }
/** * Creates an instance of a CMapAwareFont based on an indirect reference to a font. * @param refFont the indirect reference to a font */ public CMapAwareDocumentFont(PRIndirectReference refFont) : base(refFont) { fontDic = (PdfDictionary)PdfReader.GetPdfObjectRelease(refFont); InitFont(); }
/** Creates a new instance of DocumentFont */ internal DocumentFont(PRIndirectReference refFont) { this.refFont = refFont; font = (PdfDictionary)PdfReader.GetPdfObject(refFont); Init(); }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected virtual PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return theRef; } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } PdfObject obj = PdfReader.GetPdfObjectRelease(inp); if (obj != null && obj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return theRef; } } iRef.SetCopied(); obj = CopyObject(obj); AddToBody(obj, theRef); return theRef; }
/** * @throws IOException */ private void ReadDecryptedDocObj() { if (encrypted) return; PdfObject encDic = trailer.Get(PdfName.ENCRYPT); if (encDic == null || encDic.ToString().Equals("null")) return; encryptionError = true; byte[] encryptionKey = null; encrypted = true; PdfDictionary enc = (PdfDictionary)GetPdfObject(encDic); String s; PdfObject o; PdfArray documentIDs = trailer.GetAsArray(PdfName.ID); byte[] documentID = null; if (documentIDs != null) { o = documentIDs[0]; strings.Remove((PdfString)o); s = o.ToString(); documentID = DocWriter.GetISOBytes(s); if (documentIDs.Size > 1) strings.Remove((PdfString)documentIDs[1]); } // just in case we have a broken producer if (documentID == null) documentID = new byte[0]; byte[] uValue = null; byte[] oValue = null; int cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; int lengthValue = 0; PdfObject filter = GetPdfObjectRelease(enc.Get(PdfName.FILTER)); if (filter.Equals(PdfName.STANDARD)) { s = enc.Get(PdfName.U).ToString(); strings.Remove((PdfString)enc.Get(PdfName.U)); uValue = DocWriter.GetISOBytes(s); s = enc.Get(PdfName.O).ToString(); strings.Remove((PdfString)enc.Get(PdfName.O)); oValue = DocWriter.GetISOBytes(s); if (enc.Contains(PdfName.OE)) strings.Remove((PdfString)enc.Get(PdfName.OE)); if (enc.Contains(PdfName.UE)) strings.Remove((PdfString)enc.Get(PdfName.UE)); if (enc.Contains(PdfName.PERMS)) strings.Remove((PdfString)enc.Get(PdfName.PERMS)); o = enc.Get(PdfName.P); if (!o.IsNumber()) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.p.value")); pValue = ((PdfNumber)o).IntValue; o = enc.Get(PdfName.R); if (!o.IsNumber()) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.r.value")); rValue = ((PdfNumber)o).IntValue; switch (rValue) { case 2: cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; break; case 3: o = enc.Get(PdfName.LENGTH); if (!o.IsNumber()) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.length.value")); lengthValue = ( (PdfNumber) o).IntValue; if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.length.value")); cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; break; case 4: PdfDictionary dic = (PdfDictionary)enc.Get(PdfName.CF); if (dic == null) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("cf.not.found.encryption")); dic = (PdfDictionary)dic.Get(PdfName.STDCF); if (dic == null) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("stdcf.not.found.encryption")); if (PdfName.V2.Equals(dic.Get(PdfName.CFM))) cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; else if (PdfName.AESV2.Equals(dic.Get(PdfName.CFM))) cryptoMode = PdfWriter.ENCRYPTION_AES_128; else throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("no.compatible.encryption.found")); PdfObject em = enc.Get(PdfName.ENCRYPTMETADATA); if (em != null && em.ToString().Equals("false")) cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA; break; case 5: cryptoMode = PdfWriter.ENCRYPTION_AES_256; PdfObject em5 = enc.Get(PdfName.ENCRYPTMETADATA); if (em5 != null && em5.ToString().Equals("false")) cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA; break; default: throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("unknown.encryption.type.r.eq.1", rValue)); } } else if (filter.Equals(PdfName.PUBSEC)) { bool foundRecipient = false; byte[] envelopedData = null; PdfArray recipients = null; o = enc.Get(PdfName.V); if (!o.IsNumber()) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.v.value")); int vValue = ((PdfNumber)o).IntValue; switch(vValue) { case 1: cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40; lengthValue = 40; recipients = (PdfArray)enc.Get(PdfName.RECIPIENTS); break; case 2: o = enc.Get(PdfName.LENGTH); if (!o.IsNumber()) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.length.value")); lengthValue = ( (PdfNumber) o).IntValue; if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("illegal.length.value")); cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; recipients = (PdfArray)enc.Get(PdfName.RECIPIENTS); break; case 4: case 5: PdfDictionary dic = (PdfDictionary)enc.Get(PdfName.CF); if (dic == null) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("cf.not.found.encryption")); dic = (PdfDictionary)dic.Get(PdfName.DEFAULTCRYPTFILTER); if (dic == null) throw new InvalidPdfException(MessageLocalization.GetComposedMessage("defaultcryptfilter.not.found.encryption")); if (PdfName.V2.Equals(dic.Get(PdfName.CFM))) { cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128; lengthValue = 128; } else if (PdfName.AESV2.Equals(dic.Get(PdfName.CFM))) { cryptoMode = PdfWriter.ENCRYPTION_AES_128; lengthValue = 128; } else if (PdfName.AESV3.Equals(dic.Get(PdfName.CFM))) { cryptoMode = PdfWriter.ENCRYPTION_AES_256; lengthValue = 256; } else throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("no.compatible.encryption.found")); PdfObject em = dic.Get(PdfName.ENCRYPTMETADATA); if (em != null && em.ToString().Equals("false")) cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA; recipients = (PdfArray)dic.Get(PdfName.RECIPIENTS); break; default: throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("unknown.encryption.type.v.eq.1", vValue)); } for (int i = 0; i<recipients.Size; i++) { PdfObject recipient = recipients[i]; if (recipient is PdfString) strings.Remove((PdfString)recipient); CmsEnvelopedData data = null; data = new CmsEnvelopedData(recipient.GetBytes()); foreach (RecipientInformation recipientInfo in data.GetRecipientInfos().GetRecipients()) { if (recipientInfo.RecipientID.Match(certificate) && !foundRecipient) { envelopedData = recipientInfo.GetContent(certificateKey); foundRecipient = true; } } } if (!foundRecipient || envelopedData == null) { throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("bad.certificate.and.key")); } IDigest sh; if ((cryptoMode & PdfWriter.ENCRYPTION_MASK) == PdfWriter.ENCRYPTION_AES_256) sh = DigestUtilities.GetDigest("SHA-256"); else sh = DigestUtilities.GetDigest("SHA-1"); sh.BlockUpdate(envelopedData, 0, 20); for (int i=0; i<recipients.Size; i++) { byte[] encodedRecipient = recipients[i].GetBytes(); sh.BlockUpdate(encodedRecipient, 0, encodedRecipient.Length); } if ((cryptoMode & PdfWriter.DO_NOT_ENCRYPT_METADATA) != 0) sh.BlockUpdate(PdfEncryption.metadataPad, 0, PdfEncryption.metadataPad.Length); encryptionKey = new byte[sh.GetDigestSize()]; sh.DoFinal(encryptionKey, 0); } decrypt = new PdfEncryption(); decrypt.SetCryptoMode(cryptoMode, lengthValue); if (filter.Equals(PdfName.STANDARD)) { if (rValue == 5) { ownerPasswordUsed = decrypt.ReadKey(enc, password); pValue = decrypt.GetPermissions(); } else { //check by owner password decrypt.SetupByOwnerPassword(documentID, password, uValue, oValue, pValue); if (!EqualsArray(uValue, decrypt.userKey, (rValue == 3 || rValue == 4) ? 16 : 32)) { //check by user password decrypt.SetupByUserPassword(documentID, password, oValue, pValue); if (!EqualsArray(uValue, decrypt.userKey, (rValue == 3 || rValue == 4) ? 16 : 32)) { throw new BadPasswordException(MessageLocalization.GetComposedMessage("bad.user.password")); } } else ownerPasswordUsed = true; } } else if (filter.Equals(PdfName.PUBSEC)) { if ((cryptoMode & PdfWriter.ENCRYPTION_MASK) == PdfWriter.ENCRYPTION_AES_256) decrypt.SetKey(encryptionKey); else decrypt.SetupByEncryptionKey(encryptionKey, lengthValue); ownerPasswordUsed = true; } for (int k = 0; k < strings.Count; ++k) { PdfString str = strings[k]; str.Decrypt(this); } if (encDic.IsIndirect()) { cryptoRef = (PRIndirectReference)encDic; xrefObj[cryptoRef.Number] = null; } encryptionError = false; }
/** Creates a new instance of DocumentFont */ internal DocumentFont(PdfDictionary font) { this.refFont = null; this.font = font; Init(); }
private void OutlineTravel(PRIndirectReference outline) { while (outline != null) { PdfDictionary outlineR = (PdfDictionary)PdfReader.GetPdfObjectRelease(outline); PRIndirectReference first = (PRIndirectReference)outlineR.Get(PdfName.FIRST); if (first != null) { OutlineTravel(first); } PdfReader.KillIndirect(outlineR.Get(PdfName.DEST)); PdfReader.KillIndirect(outlineR.Get(PdfName.A)); PdfReader.KillIndirect(outline); outline = (PRIndirectReference)outlineR.Get(PdfName.NEXT); } }
virtual protected internal PdfObject ReadPRObject() { tokens.NextValidToken(); PRTokeniser.TokType type = tokens.TokenType; switch (type) { case PRTokeniser.TokType.START_DIC: { ++readDepth; PdfDictionary dic = ReadDictionary(); --readDepth; long pos = tokens.FilePointer; // be careful in the trailer. May not be a "next" token. bool hasNext; do { hasNext = tokens.NextToken(); } while (hasNext && tokens.TokenType == PRTokeniser.TokType.COMMENT); if (hasNext && tokens.StringValue.Equals("stream")) { //skip whitespaces int ch; do { ch = tokens.Read(); } while (ch == 32 || ch == 9 || ch == 0 || ch == 12); if (ch != '\n') ch = tokens.Read(); if (ch != '\n') tokens.BackOnePosition(ch); PRStream stream = new PRStream(this, tokens.FilePointer); stream.Merge(dic); stream.ObjNum = objNum; stream.ObjGen = objGen; return stream; } else { tokens.Seek(pos); return dic; } } case PRTokeniser.TokType.START_ARRAY: { ++readDepth; PdfArray arr = ReadArray(); --readDepth; return arr; } case PRTokeniser.TokType.NUMBER: return new PdfNumber(tokens.StringValue); case PRTokeniser.TokType.STRING: PdfString str = new PdfString(tokens.StringValue, null).SetHexWriting(tokens.IsHexString()); str.SetObjNum(objNum, objGen); if (strings != null) strings.Add(str); return str; case PRTokeniser.TokType.NAME: { PdfName cachedName; PdfName.staticNames.TryGetValue(tokens.StringValue, out cachedName); if (readDepth > 0 && cachedName != null) { return cachedName; } else { // an indirect name (how odd...), or a non-standard one return new PdfName(tokens.StringValue, false); } } case PRTokeniser.TokType.REF: int num = tokens.Reference; PRIndirectReference refi = new PRIndirectReference(this, num, tokens.Generation); return refi; case PRTokeniser.TokType.ENDOFFILE: throw new IOException(MessageLocalization.GetComposedMessage("unexpected.end.of.file")); default: String sv = tokens.StringValue; if ("null".Equals(sv)) { if (readDepth == 0) { return new PdfNull(); } //else return PdfNull.PDFNULL; } else if ("true".Equals(sv)) { if (readDepth == 0) { return new PdfBoolean( true ); } //else return PdfBoolean.PDFTRUE; } else if ("false".Equals(sv)) { if (readDepth == 0) { return new PdfBoolean( false ); } //else return PdfBoolean.PDFFALSE; } return new PdfLiteral(-(int)type, tokens.StringValue); } }
/** Creates an independent duplicate. * @param reader the <CODE>PdfReader</CODE> to duplicate */ public PdfReader(PdfReader reader) { this.appendable = reader.appendable; this.consolidateNamedDestinations = reader.consolidateNamedDestinations; this.encrypted = reader.encrypted; this.rebuilt = reader.rebuilt; this.sharedStreams = reader.sharedStreams; this.tampered = reader.tampered; this.password = reader.password; this.pdfVersion = reader.pdfVersion; this.eofPos = reader.eofPos; this.freeXref = reader.freeXref; this.lastXref = reader.lastXref; this.newXrefType = reader.newXrefType; this.tokens = new PRTokeniser(reader.tokens.SafeFile); if (reader.decrypt != null) this.decrypt = new PdfEncryption(reader.decrypt); this.pValue = reader.pValue; this.rValue = reader.rValue; this.xrefObj = new List<PdfObject>(reader.xrefObj); for (int k = 0; k < reader.xrefObj.Count; ++k) { this.xrefObj[k] = DuplicatePdfObject(reader.xrefObj[k], this); } this.pageRefs = new PageRefs(reader.pageRefs, this); this.trailer = (PdfDictionary)DuplicatePdfObject(reader.trailer, this); this.catalog = trailer.GetAsDict(PdfName.ROOT); this.rootPages = catalog.GetAsDict(PdfName.PAGES); this.fileLength = reader.fileLength; this.partial = reader.partial; this.hybridXref = reader.hybridXref; this.objStmToOffset = reader.objStmToOffset; this.xref = reader.xref; this.cryptoRef = (PRIndirectReference)DuplicatePdfObject(reader.cryptoRef, this); this.ownerPasswordUsed = reader.ownerPasswordUsed; }
internal void InsertPage(int pageNum, PRIndirectReference refi) { --pageNum; if (refsn != null) { if (pageNum >= refsn.Count) refsn.Add(refi); else refsn.Insert(pageNum, refi); } else { ++sizep; lastPageRead = -1; if (pageNum >= Size) { refsp[Size] = refi.Number; } else { IntHashtable refs2 = new IntHashtable((refsp.Size + 1) * 2); for (IntHashtable.IntHashtableIterator it = refsp.GetEntryIterator(); it.HasNext();) { IntHashtable.IntHashtableEntry entry = (IntHashtable.IntHashtableEntry)it.Next(); int p = entry.Key; refs2[p >= pageNum ? p + 1 : p] = entry.Value; } refs2[pageNum] = refi.Number; refsp = refs2; } } }
/** Creates a new instance of DocumentFont */ internal DocumentFont(PRIndirectReference refFont) { encoding = ""; fontSpecific = false; this.refFont = refFont; fontType = FONT_TYPE_DOCUMENT; font = (PdfDictionary)PdfReader.GetPdfObject(refFont); PdfName baseFont = font.GetAsName(PdfName.BASEFONT); fontName = baseFont != null ? PdfName.DecodeName(baseFont.ToString()) : "Unspecified Font Name"; PdfName subType = font.GetAsName(PdfName.SUBTYPE); if (PdfName.TYPE1.Equals(subType) || PdfName.TRUETYPE.Equals(subType)) DoType1TT(); else { for (int k = 0; k < cjkNames.Length; ++k) { if (fontName.StartsWith(cjkNames[k])) { fontName = cjkNames[k]; cjkMirror = BaseFont.CreateFont(fontName, cjkEncs[k], false); return; } } PdfName encodingName = font.GetAsName(PdfName.ENCODING); if (encodingName != null){ String enc = PdfName.DecodeName(encodingName.ToString()); for (int k = 0; k < cjkEncs2.Length; ++k) { if (enc.StartsWith(cjkEncs2[k])) { if (k > 3) k -= 4; cjkMirror = BaseFont.CreateFont(cjkNames2[k], cjkEncs2[k], false); return; } } if (PdfName.TYPE0.Equals(subType) && enc.Equals("Identity-H")) { ProcessType0(font); isType0 = true; } } } }
/** * Reuses an existing image. * @param ref the reference to the image dictionary * @throws BadElementException on error * @return the image */ public static Image GetInstance(PRIndirectReference iref) { PdfDictionary dic = (PdfDictionary)PdfReader.GetPdfObjectRelease(iref); int width = ((PdfNumber)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.WIDTH))).IntValue; int height = ((PdfNumber)PdfReader.GetPdfObjectRelease(dic.Get(PdfName.HEIGHT))).IntValue; Image imask = null; PdfObject obj = dic.Get(PdfName.SMASK); if (obj != null && obj.IsIndirect()) { imask = GetInstance((PRIndirectReference)obj); } else { obj = dic.Get(PdfName.MASK); if (obj != null && obj.IsIndirect()) { PdfObject obj2 = PdfReader.GetPdfObjectRelease(obj); if (obj2 is PdfDictionary) imask = GetInstance((PRIndirectReference)obj); } } Image img = new ImgRaw(width, height, 1, 1, null); img.imageMask = imask; img.directReference = iref; return img; }
internal RefKey(PRIndirectReference refi) { num = refi.Number; gen = refi.Generation; }
internal void Propagate(PdfObject obj, PdfIndirectReference refo, bool restricted) { if (obj == null) { return; } // if (refo != null) // AddToBody(obj, refo); if (obj is PdfIndirectReference) { return; } switch (obj.Type) { case PdfObject.DICTIONARY: case PdfObject.STREAM: { PdfDictionary dic = (PdfDictionary)obj; foreach (PdfName key in dic.Keys) { if (restricted && (key.Equals(PdfName.PARENT) || key.Equals(PdfName.KIDS))) { continue; } PdfObject ob = dic.Get(key); if (ob != null && ob.IsIndirect()) { PRIndirectReference ind = (PRIndirectReference)ob; if (!SetVisited(ind) && !IsPage(ind)) { PdfIndirectReference refi = GetNewReference(ind); Propagate(PdfReader.GetPdfObjectRelease(ind), refi, restricted); } } else { Propagate(ob, null, restricted); } } break; } case PdfObject.ARRAY: { //PdfArray arr = new PdfArray(); for (ListIterator <PdfObject> it = ((PdfArray)obj).GetListIterator(); it.HasNext();) { PdfObject ob = it.Next(); if (ob != null && ob.IsIndirect()) { PRIndirectReference ind = (PRIndirectReference)ob; if (!IsVisited(ind) && !IsPage(ind)) { PdfIndirectReference refi = GetNewReference(ind); Propagate(PdfReader.GetPdfObjectRelease(ind), refi, restricted); } } else { Propagate(ob, null, restricted); } } break; } case PdfObject.INDIRECT: { throw new Exception(MessageLocalization.GetComposedMessage("reference.pointing.to.reference")); } } }
/** * Add an imported page to our output * @param iPage an imported page * @throws IOException, BadPdfFormatException */ public virtual void AddPage(PdfImportedPage iPage) { if (mergeFields && !mergeFieldsInternalCall) { throw new ArgumentException(MessageLocalization.GetComposedMessage("1.method.cannot.be.used.in.mergeFields.mode.please.use.addDocument", "addPage")); } int pageNum = SetFromIPage(iPage); PdfDictionary thePage = reader.GetPageN(pageNum); PRIndirectReference origRef = reader.GetPageOrigRef(pageNum); reader.ReleasePage(pageNum); RefKey key = new RefKey(origRef); PdfIndirectReference pageRef; IndirectReferences iRef; if (indirects.TryGetValue(key, out iRef) && !iRef.Copied) { pageReferences.Add(iRef.Ref); iRef.SetCopied(); } pageRef = CurrentPage; if (iRef == null) { iRef = new IndirectReferences(pageRef); indirects[key] = iRef; } iRef.SetCopied(); if (tagged) structTreeRootReference = (PRIndirectReference)reader.Catalog.Get(PdfName.STRUCTTREEROOT); PdfDictionary newPage = CopyDictionary(thePage); root.AddPage(newPage); iPage.SetCopied(); ++currentPageNumber; structTreeRootReference = null; }
internal static String GetCOName(PdfReader reader, PRIndirectReference refi) { String name = ""; while (refi != null) { PdfObject obj = PdfReader.GetPdfObject(refi); if (obj == null || obj.Type != PdfObject.DICTIONARY) break; PdfDictionary dic = (PdfDictionary)obj; PdfString t = dic.GetAsString(PdfName.T); if (t != null) { name = t.ToUnicodeString()+ "." + name; } refi = (PRIndirectReference)dic.Get(PdfName.PARENT); } if (name.EndsWith(".")) name = name.Substring(0, name.Length - 1); return name; }
virtual protected PdfIndirectReference GetNewReference(PRIndirectReference refi) { return(new PdfIndirectReference(0, GetNewObjectNumber(refi.Reader, refi.Number, 0))); }
protected PdfIndirectReference GetNewReference(PRIndirectReference refi) { return new PdfIndirectReference(0, GetNewObjectNumber(refi.Reader, refi.Number, 0)); }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected virtual PdfIndirectReference CopyIndirect(PRIndirectReference inp) { return CopyIndirect(inp, false, false); }
/** * Checks if a reference refers to a page object. * @param ref the reference that needs to be checked * @return true is the reference refers to a page object. */ protected internal bool IsPage(PRIndirectReference refi) { IntHashtable refs; if (pages2intrefs.TryGetValue(refi.Reader, out refs)) return refs.ContainsKey(refi.Number); else return false; }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected internal virtual PdfIndirectReference CopyIndirect(PRIndirectReference inp, bool keepStructure, bool directRootKids) { PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iref; indirects.TryGetValue(key, out iref); PdfObject obj = PdfReader.GetPdfObjectRelease(inp); if ((keepStructure) && (directRootKids)) if (obj is PdfDictionary) { PdfDictionary dict = (PdfDictionary) obj; if (dict.Contains(PdfName.PG)) return null; } if (iref != null) { theRef = iref.Ref; if (iref.Copied) { return theRef; } } else { theRef = body.PdfIndirectReference; iref = new IndirectReferences(theRef); indirects[key] = iref; } if (obj != null && obj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return theRef; } } iref.SetCopied(); parentObjects[obj] = inp; PdfObject res = CopyObject(obj, keepStructure, directRootKids); if (disableIndirects.Contains(obj)) iref.Copied = false; if ((res != null) && !(res is PdfNull)) { AddToBody(res, theRef); return theRef; } indirects.Remove(key); return null; }
/** * Creates a font based on an existing document font. The created font font may not * behave as expected, depending on the encoding or subset. * @param fontRef the reference to the document font * @return the font */ public static BaseFont CreateFont(PRIndirectReference fontRef) { return new DocumentFont(fontRef); }
/** * Checks if a reference has already been "visited" in the copy process. * @param ref the reference that needs to be checked * @return true if the reference was already visited */ virtual protected internal bool IsVisited(PRIndirectReference refi) { IntHashtable refs; if (visited.TryGetValue(refi.Reader, out refs)) return refs.ContainsKey(refi.Number); else return false; }
internal FieldInformation(String fieldName, PdfDictionary info, PRIndirectReference refi) { this.fieldName = fieldName; this.info = info; this.refi = refi; }
private void IteratePages(PRIndirectReference rpage) { PdfDictionary page = (PdfDictionary)GetPdfObject(rpage); if (page == null) return; PdfArray kidsPR = page.GetAsArray(PdfName.KIDS); if (kidsPR == null) { page.Put(PdfName.TYPE, PdfName.PAGE); PdfDictionary dic = pageInh[pageInh.Count - 1]; foreach (PdfName key in dic.Keys) { if (page.Get(key) == null) page.Put(key, dic.Get(key)); } if (page.Get(PdfName.MEDIABOX) == null) { PdfArray arr = new PdfArray(new float[]{0,0,PageSize.LETTER.Right,PageSize.LETTER.Top}); page.Put(PdfName.MEDIABOX, arr); } refsn.Add(rpage); } else { page.Put(PdfName.TYPE, PdfName.PAGES); PushPageAttributes(page); for (int k = 0; k < kidsPR.Size; ++k){ PdfObject obj = kidsPR[k]; if (!obj.IsIndirect()) { while (k < kidsPR.Size) kidsPR.Remove(k); break; } IteratePages((PRIndirectReference)obj); } PopPageAttributes(); } }
internal void InsertPage(int pageNumber, Rectangle mediabox) { Rectangle media = new Rectangle(mediabox); int rotation = media.Rotation % 360; PdfDictionary page = new PdfDictionary(PdfName.PAGE); page.Put(PdfName.RESOURCES, new PdfDictionary()); page.Put(PdfName.ROTATE, new PdfNumber(rotation)); page.Put(PdfName.MEDIABOX, new PdfRectangle(media, rotation)); PRIndirectReference pref = reader.AddPdfObject(page); PdfDictionary parent; PRIndirectReference parentRef; if (pageNumber > reader.NumberOfPages) { PdfDictionary lastPage = reader.GetPageNRelease(reader.NumberOfPages); parentRef = (PRIndirectReference)lastPage.Get(PdfName.PARENT); parentRef = new PRIndirectReference(reader, parentRef.Number); parent = (PdfDictionary)PdfReader.GetPdfObject(parentRef); PdfArray kids = (PdfArray)PdfReader.GetPdfObject(parent.Get(PdfName.KIDS), parent); kids.Add(pref); MarkUsed(kids); reader.pageRefs.InsertPage(pageNumber, pref); } else { if (pageNumber < 1) pageNumber = 1; PdfDictionary firstPage = reader.GetPageN(pageNumber); PRIndirectReference firstPageRef = reader.GetPageOrigRef(pageNumber); reader.ReleasePage(pageNumber); parentRef = (PRIndirectReference)firstPage.Get(PdfName.PARENT); parentRef = new PRIndirectReference(reader, parentRef.Number); parent = (PdfDictionary)PdfReader.GetPdfObject(parentRef); PdfArray kids = (PdfArray)PdfReader.GetPdfObject(parent.Get(PdfName.KIDS), parent); int len = kids.Size; int num = firstPageRef.Number; for (int k = 0; k < len; ++k) { PRIndirectReference cur = (PRIndirectReference)kids[k]; if (num == cur.Number) { kids.Add(k, pref); break; } } if (len == kids.Size) throw new Exception(MessageLocalization.GetComposedMessage("internal.inconsistence")); MarkUsed(kids); reader.pageRefs.InsertPage(pageNumber, pref); CorrectAcroFieldPages(pageNumber); } page.Put(PdfName.PARENT, parentRef); while (parent != null) { MarkUsed(parent); PdfNumber count = (PdfNumber)PdfReader.GetPdfObjectRelease(parent.Get(PdfName.COUNT)); parent.Put(PdfName.COUNT, new PdfNumber(count.IntValue + 1)); parent = parent.GetAsDict(PdfName.PARENT); } }