private static string getCoName(PdfReader reader, PrIndirectReference refi) { var name = ""; while (refi != null) { var obj = PdfReader.GetPdfObject(refi); if (obj == null || obj.Type != PdfObject.DICTIONARY) { break; } var dic = (PdfDictionary)obj; var 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); }
/// <summary> /// 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. /// </summary> protected virtual PdfIndirectReference CopyIndirect(PrIndirectReference inp) { PdfIndirectReference theRef; var key = new RefKey(inp); var 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; } var obj = PdfReader.GetPdfObjectRelease(inp); if (obj != null && obj.IsDictionary()) { var 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); }
/// <summary> /// Add an imported page to our output /// @throws IOException, BadPdfFormatException /// </summary> /// <param name="iPage">an imported page</param> 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 = (IndirectReferences)Indirects[key]; 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); ++currentPageNumber; }
/// <summary> /// convenience method. Given a reader, set our "globals" /// </summary> protected void SetFromReader(PdfReader reader) { Reader = reader; Indirects = (Hashtable)IndirectMap[reader]; if (Indirects == null) { Indirects = new Hashtable(); IndirectMap[reader] = Indirects; var catalog = reader.Catalog; PrIndirectReference refi = null; var 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); } }
protected void CloseIt() { for (var k = 0; k < Readers.Count; ++k) { ((PdfReader)Readers[k]).RemoveFields(); } for (var r = 0; r < Readers.Count; ++r) { var reader = (PdfReader)Readers[r]; for (var page = 1; page <= reader.NumberOfPages; ++page) { PageRefs.Add(GetNewReference(reader.GetPageOrigRef(page))); PageDics.Add(reader.GetPageN(page)); } } MergeFields(); CreateAcroForms(); for (var r = 0; r < Readers.Count; ++r) { var reader = (PdfReader)Readers[r]; for (var page = 1; page <= reader.NumberOfPages; ++page) { var dic = reader.GetPageN(page); var pageRef = GetNewReference(reader.GetPageOrigRef(page)); var parent = Root.AddPageRef(pageRef); dic.Put(PdfName.Parent, parent); Propagate(dic, pageRef, false); } } foreach (DictionaryEntry entry in Readers2Intrefs) { var reader = (PdfReader)entry.Key; try { File = reader.SafeFile; File.ReOpen(); var t = (IntHashtable)entry.Value; var keys = t.ToOrderedKeys(); for (var k = 0; k < keys.Length; ++k) { var 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(); }
/// <summary> /// 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. /// </summary> protected override PdfIndirectReference CopyIndirect(PrIndirectReference inp) { var srcObj = PdfReader.GetPdfObjectRelease(inp); ByteStore streamKey = null; var validStream = false; if (srcObj.IsStream()) { streamKey = new ByteStore((PrStream)srcObj); validStream = true; var streamRef = (PdfIndirectReference)_streamMap[streamKey]; if (streamRef != null) { return(streamRef); } } PdfIndirectReference theRef; var key = new RefKey(inp); var 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; } if (srcObj != null && srcObj.IsDictionary()) { var type = PdfReader.GetPdfObjectRelease(((PdfDictionary)srcObj).Get(PdfName.TYPE)); if (type != null && PdfName.Page.Equals(type)) { return(theRef); } } iRef.SetCopied(); if (validStream) { _streamMap[streamKey] = theRef; } var obj = CopyObject(srcObj); AddToBody(obj, theRef); return(theRef); }
/// <summary> /// Checks if a reference refers to a page object. /// </summary> /// <param name="refi">the reference that needs to be checked</param> /// <returns>true is the reference refers to a page object.</returns> protected internal bool IsPage(PrIndirectReference refi) { IntHashtable refs = (IntHashtable)Pages2Intrefs[refi.Reader]; if (refs != null) { return(refs.ContainsKey(refi.Number)); } else { return(false); } }
/// <summary> /// Checks if a reference has already been "visited" in the copy process. /// </summary> /// <param name="refi">the reference that needs to be checked</param> /// <returns>true if the reference was already visited</returns> protected internal bool IsVisited(PrIndirectReference refi) { var refs = (IntHashtable)Visited[refi.Reader]; if (refs != null) { return(refs.ContainsKey(refi.Number)); } else { return(false); } }
/// <summary> /// After reading, we index all of the fields. Recursive. /// </summary> /// <param name="fieldlist">An array of fields</param> /// <param name="fieldDict">the last field dictionary we encountered (recursively)</param> /// <param name="title">the pathname of the field, up to this point or null</param> protected void IterateFields(PdfArray fieldlist, PrIndirectReference fieldDict, string title) { 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 myTitle = title; PdfString tField = (PdfString)dict.Get(PdfName.T); bool isFieldDict = tField != null; if (isFieldDict) { myFieldDict = refi; if (title == null) { myTitle = tField.ToString(); } else { myTitle = title + '.' + tField; } } PdfArray kids = (PdfArray)dict.Get(PdfName.Kids); if (kids != null) { PushAttrib(dict); IterateFields(kids, myFieldDict, myTitle); 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(myTitle)); FieldInformation fi = new FieldInformation(myTitle, mergedDict, myFieldDict); fields.Add(fi); FieldByName[myTitle] = fi; } } } }
/// <summary> /// Sets a reference to "visited" in the copy process. /// </summary> /// <param name="refi">the reference that needs to be set to "visited"</param> /// <returns>true if the reference was set to visited</returns> protected internal bool SetVisited(PrIndirectReference refi) { var refs = (IntHashtable)Visited[refi.Reader]; if (refs != null) { var old = refs[refi.Number]; refs[refi.Number] = 1; return(old != 0); } else { return(false); } }
/// <summary> /// Creates a new instance of DocumentFont /// </summary> internal DocumentFont(PrIndirectReference refFont) { encoding = ""; FontSpecific = false; _refFont = refFont; fontType = FONT_TYPE_DOCUMENT; _font = (PdfDictionary)PdfReader.GetPdfObject(refFont); _fontName = PdfName.DecodeName(_font.GetAsName(PdfName.Basefont).ToString()); var subType = _font.GetAsName(PdfName.Subtype); if (PdfName.Type1.Equals(subType) || PdfName.Truetype.Equals(subType)) { doType1Tt(); } else { for (var k = 0; k < _cjkNames.Length; ++k) { if (_fontName.StartsWith(_cjkNames[k])) { _fontName = _cjkNames[k]; _cjkMirror = CreateFont(_fontName, _cjkEncs[k], false); return; } } var enc = PdfName.DecodeName(_font.GetAsName(PdfName.Encoding).ToString()); for (var k = 0; k < _cjkEncs2.Length; ++k) { if (enc.StartsWith(_cjkEncs2[k])) { if (k > 3) { k -= 4; } _cjkMirror = CreateFont(_cjkNames2[k], _cjkEncs2[k], false); return; } } if (PdfName.Type0.Equals(subType) && enc.Equals("Identity-H")) { processType0(_font); _isType0 = true; } } }
/// <summary> /// Copy the acroform for an input document. Note that you can only have one, /// we make no effort to merge them. /// @throws IOException, BadPdfFormatException /// </summary> /// <param name="reader">The reader of the input file that is being copied</param> public void CopyAcroForm(PdfReader reader) { SetFromReader(reader); var catalog = reader.Catalog; PrIndirectReference hisRef = null; var o = catalog.Get(PdfName.Acroform); if (o != null && o.Type == PdfObject.INDIRECT) { hisRef = (PrIndirectReference)o; } if (hisRef == null) { return; // bugfix by John Engla } var key = new RefKey(hisRef); PdfIndirectReference myRef; var iRef = (IndirectReferences)Indirects[key]; if (iRef != null) { acroForm = myRef = iRef.Ref; } else { acroForm = myRef = Body.PdfIndirectReference; iRef = new IndirectReferences(myRef); Indirects[key] = iRef; } if (!iRef.Copied) { iRef.SetCopied(); var theForm = CopyDictionary((PdfDictionary)PdfReader.GetPdfObject(hisRef)); AddToBody(theForm, myRef); } }
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("Page not found."); }
protected PdfIndirectReference GetNewReference(PrIndirectReference refi) { return(new PdfIndirectReference(0, GetNewObjectNumber(refi.Reader, refi.Number, 0))); }
internal FieldInformation(string name, PdfDictionary info, PrIndirectReference refi) { this.name = name; this.info = info; Refi = refi; }
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 it = ((PdfArray)obj).GetListIterator(); it.HasNext();) { PdfObject ob = (PdfObject)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("Reference pointing to reference."); } } }