/// <summary>Retrieves the names stored in the name tree</summary> /// <returns>Map containing the PdfObjects stored in the tree</returns> public virtual IDictionary <String, PdfObject> GetNames() { if (items.Count > 0) { return(items); } PdfDictionary dictionary = catalog.GetPdfObject().GetAsDictionary(PdfName.Names); if (dictionary != null) { dictionary = dictionary.GetAsDictionary(treeType); if (dictionary != null) { items = ReadTree(dictionary); //@TODO It's done for auto porting to itextsharp, cuz u cannot change collection which you iterate // in for loop (even if you change only value of a Map entry) in .NET. Java doesn't have such a problem. // We should find a better solution in the future. ICollection <String> keys = new HashSet <String>(); keys.AddAll(items.Keys); foreach (String key in keys) { if (treeType.Equals(PdfName.Dests)) { PdfArray arr = GetDestArray(items.Get(key)); if (arr != null) { items.Put(key, arr); } else { items.JRemove(key); } } else { if (items.Get(key) == null) { items.JRemove(key); } } } } } if (treeType.Equals(PdfName.Dests)) { PdfDictionary destinations = catalog.GetPdfObject().GetAsDictionary(PdfName.Dests); if (destinations != null) { ICollection <PdfName> keys = destinations.KeySet(); foreach (PdfName key in keys) { PdfArray array = GetDestArray(destinations.Get(key)); if (array == null) { continue; } items.Put(key.GetValue(), array); } } } return(items); }
private void LoadPage(int pageNum) { PdfDictionary targetPage = pageRefs[pageNum]; if (targetPage != null) { return; } //if we go here, we have to split PdfPages that contains pageNum int parentIndex = FindPageParent(pageNum); PdfPages parent = parents[parentIndex]; PdfArray kids = parent.GetKids(); if (kids == null) { throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1); } int kidsCount = parent.GetCount(); // we should handle separated pages, it means every PdfArray kids must contain either PdfPage or PdfPages, // mix of PdfPage and PdfPages not allowed. bool findPdfPages = false; // NOTE optimization? when we already found needed index for (int i = 0; i < kids.Size(); i++) { PdfDictionary page = kids.GetAsDictionary(i); if (page == null) { // null values not allowed in pages tree. throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1); } PdfObject pageKids = page.Get(PdfName.Kids); if (pageKids != null) { if (pageKids.IsArray()) { findPdfPages = true; } else { // kids must be of type array throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1); } } } if (findPdfPages) { // handle mix of PdfPage and PdfPages. // handle count property! IList <PdfPages> newParents = new List <PdfPages>(kids.Size()); PdfPages lastPdfPages = null; for (int i = 0; i < kids.Size() && kidsCount > 0; i++) { PdfDictionary pdfPagesObject = kids.GetAsDictionary(i); if (pdfPagesObject.GetAsArray(PdfName.Kids) == null) { // pdfPagesObject is PdfPage if (lastPdfPages == null) { // possible if only first kid is PdfPage lastPdfPages = new PdfPages(parent.GetFrom(), document, parent); kids.Set(i, lastPdfPages.GetPdfObject()); newParents.Add(lastPdfPages); } else { // Only remove from kids if we did not replace the entry with new PdfPages kids.Remove(i); i--; } // decrement count first so that page is not counted twice when moved to lastPdfPages parent.DecrementCount(); lastPdfPages.AddPage(pdfPagesObject); kidsCount--; } else { // pdfPagesObject is PdfPages int from = lastPdfPages == null?parent.GetFrom() : lastPdfPages.GetFrom() + lastPdfPages.GetCount(); lastPdfPages = new PdfPages(from, kidsCount, pdfPagesObject, parent); newParents.Add(lastPdfPages); kidsCount -= lastPdfPages.GetCount(); } } parents.JRemoveAt(parentIndex); for (int i = newParents.Count - 1; i >= 0; i--) { parents.Add(parentIndex, newParents[i]); } // recursive call, to load needed pageRef. // NOTE optimization? add to loadPage startParentIndex. LoadPage(pageNum); } else { int from = parent.GetFrom(); // Possible exception in case kids.getSize() < parent.getCount(). // In any case parent.getCount() has higher priority. // NOTE optimization? when we already found needed index for (int i = 0; i < parent.GetCount(); i++) { pageRefs[from + i] = kids.GetAsDictionary(i); } } }
/// <summary>Retrieves the names stored in the name tree</summary> /// <returns>Map containing the PdfObjects stored in the tree</returns> public virtual IDictionary <String, PdfObject> GetNames() { if (items.Count > 0) { return(items); } PdfDictionary dictionary = catalog.GetPdfObject().GetAsDictionary(PdfName.Names); if (dictionary != null) { dictionary = dictionary.GetAsDictionary(treeType); if (dictionary != null) { items = ReadTree(dictionary); // A separate collection for keys is used for auto porting to C#, because in C# // it is impossible to change the collection which you iterate in for loop ICollection <String> keys = new HashSet <String>(); keys.AddAll(items.Keys); foreach (String key in keys) { if (treeType.Equals(PdfName.Dests)) { PdfArray arr = GetDestArray(items.Get(key)); if (arr != null) { items.Put(key, arr); } else { items.JRemove(key); } } else { if (items.Get(key) == null) { items.JRemove(key); } } } } } if (treeType.Equals(PdfName.Dests)) { PdfDictionary destinations = catalog.GetPdfObject().GetAsDictionary(PdfName.Dests); if (destinations != null) { ICollection <PdfName> keys = destinations.KeySet(); foreach (PdfName key in keys) { PdfArray array = GetDestArray(destinations.Get(key)); if (array == null) { continue; } items.Put(key.GetValue(), array); } } } return(items); }
/// <exception cref="iText.Kernel.XMP.XMPException"/> internal static void AppendDocumentInfoToMetadata(PdfDocumentInfo info, XMPMeta xmpMeta) { PdfDictionary docInfo = info.GetPdfObject(); if (docInfo != null) { PdfName key; PdfObject obj; String value; foreach (PdfName pdfName in docInfo.KeySet()) { key = pdfName; obj = docInfo.Get(key); if (obj == null) { continue; } if (obj.IsString()) { value = ((PdfString)obj).ToUnicodeString(); } else { if (obj.IsName()) { value = ((PdfName)obj).GetValue(); } else { continue; } } if (PdfName.Title.Equals(key)) { xmpMeta.SetLocalizedText(XMPConst.NS_DC, PdfConst.Title, XMPConst.X_DEFAULT, XMPConst.X_DEFAULT, value); } else { if (PdfName.Author.Equals(key)) { foreach (String v in iText.IO.Util.StringUtil.Split(value, ",|;")) { if (v.Trim().Length > 0) { AppendArrayItemIfDoesNotExist(xmpMeta, XMPConst.NS_DC, PdfConst.Creator, v.Trim()); } } } else { if (PdfName.Subject.Equals(key)) { xmpMeta.SetLocalizedText(XMPConst.NS_DC, PdfConst.Description, XMPConst.X_DEFAULT, XMPConst.X_DEFAULT, value ); } else { if (PdfName.Keywords.Equals(key)) { foreach (String v in iText.IO.Util.StringUtil.Split(value, ",|;")) { if (v.Trim().Length > 0) { AppendArrayItemIfDoesNotExist(xmpMeta, XMPConst.NS_DC, PdfConst.Subject, v.Trim()); } } xmpMeta.SetProperty(XMPConst.NS_PDF, PdfConst.Keywords, value); } else { if (PdfName.Creator.Equals(key)) { xmpMeta.SetProperty(XMPConst.NS_XMP, PdfConst.CreatorTool, value); } else { if (PdfName.Producer.Equals(key)) { xmpMeta.SetProperty(XMPConst.NS_PDF, PdfConst.Producer, value); } else { if (PdfName.CreationDate.Equals(key)) { xmpMeta.SetProperty(XMPConst.NS_XMP, PdfConst.CreateDate, PdfDate.GetW3CDate(value)); } else { if (PdfName.ModDate.Equals(key)) { xmpMeta.SetProperty(XMPConst.NS_XMP, PdfConst.ModifyDate, PdfDate.GetW3CDate(value)); } else { if (PdfName.Trapped.Equals(key)) { xmpMeta.SetProperty(XMPConst.NS_PDF, PdfConst.Trapped, value); } } } } } } } } } } } }