private static PdfObject CopyObjectKid(PdfObject kid, PdfDictionary copiedParent, PdfDictionary destPage, bool parentChangePg, StructureTreeCopier.StructElemCopyingParams copyingParams) { if (kid.IsNumber()) { if (!parentChangePg) { copyingParams.GetToDocument().GetStructTreeRoot().GetParentTreeHandler().RegisterMcr(new PdfMcrNumber((PdfNumber )kid, new PdfStructElem(copiedParent))); return(kid); } } else { if (kid.IsDictionary()) { PdfDictionary kidAsDict = (PdfDictionary)kid; if (copyingParams.GetObjectsToCopy().Contains(kidAsDict)) { bool hasParent = kidAsDict.ContainsKey(PdfName.P); PdfDictionary copiedKid = CopyObject(kidAsDict, destPage, parentChangePg, copyingParams); if (hasParent) { copiedKid.Put(PdfName.P, copiedParent); } else { PdfMcr mcr; if (copiedKid.ContainsKey(PdfName.Obj)) { mcr = new PdfObjRef(copiedKid, new PdfStructElem(copiedParent)); PdfDictionary contentItemObject = copiedKid.GetAsDictionary(PdfName.Obj); if (PdfName.Link.Equals(contentItemObject.GetAsName(PdfName.Subtype)) && !contentItemObject.ContainsKey(PdfName .P)) { // Some link annotations may be not copied, because their destination page is not copied. return(null); } contentItemObject.Put(PdfName.StructParent, new PdfNumber((int)copyingParams.GetToDocument().GetNextStructParentIndex ())); } else { mcr = new PdfMcrDictionary(copiedKid, new PdfStructElem(copiedParent)); } copyingParams.GetToDocument().GetStructTreeRoot().GetParentTreeHandler().RegisterMcr(mcr); } return(copiedKid); } } } return(null); }
private static StructureTreeCopier.CopyStructureResult CopyStructure(PdfDocument destDocument, IDictionary <PdfPage, PdfPage> page2page, PdfDocument callingDocument, bool copyFromDestDocument) { PdfDocument fromDocument = copyFromDestDocument ? destDocument : callingDocument; IDictionary<PdfDictionary, PdfDictionary> topsToFirstDestPage = new Dictionary<PdfDictionary, PdfDictionary >(); ICollection<PdfObject> objectsToCopy = new HashSet<PdfObject>(); IDictionary<PdfDictionary, PdfDictionary> page2pageDictionaries = new Dictionary<PdfDictionary, PdfDictionary >(); foreach (KeyValuePair<PdfPage, PdfPage> page in page2page) { page2pageDictionaries.Put(page.Key.GetPdfObject(), page.Value.GetPdfObject()); ICollection<PdfMcr> mcrs = fromDocument.GetStructTreeRoot().GetPageMarkedContentReferences(page.Key); if (mcrs != null) { foreach (PdfMcr mcr in mcrs) { if (mcr is PdfMcrDictionary || mcr is PdfObjRef) { objectsToCopy.Add(mcr.GetPdfObject()); } PdfDictionary top = AddAllParentsToSet(mcr, objectsToCopy); if (top != null) { if (top.IsFlushed()) { throw new PdfException(PdfException.CannotCopyFlushedTag); } if (!topsToFirstDestPage.ContainsKey(top)) { topsToFirstDestPage.Put(top, page.Value.GetPdfObject()); } } } } } IList<PdfDictionary> topsInOriginalOrder = new List<PdfDictionary>(); foreach (IStructureNode kid in fromDocument.GetStructTreeRoot().GetKids()) { if (kid == null) { continue; } PdfDictionary kidObject = ((PdfStructElem)kid).GetPdfObject(); if (topsToFirstDestPage.ContainsKey(kidObject)) { topsInOriginalOrder.Add(kidObject); } } StructureTreeCopier.StructElemCopyingParams structElemCopyingParams = new StructureTreeCopier.StructElemCopyingParams (objectsToCopy, destDocument, page2pageDictionaries, copyFromDestDocument); PdfStructTreeRoot destStructTreeRoot = destDocument.GetStructTreeRoot(); destStructTreeRoot.MakeIndirect(destDocument); IList<PdfDictionary> copiedTops = new List<PdfDictionary>(); foreach (PdfDictionary top in topsInOriginalOrder) { PdfDictionary copied = CopyObject(top, topsToFirstDestPage.Get(top), false, structElemCopyingParams); copiedTops.Add(copied); } return new StructureTreeCopier.CopyStructureResult(copiedTops, structElemCopyingParams.GetCopiedNamespaces ()); }
private static PdfDictionary CopyNamespaceDict(PdfDictionary srcNsDict, StructureTreeCopier.StructElemCopyingParams copyingParams) { IList <PdfName> excludeKeys = JavaCollectionsUtil.SingletonList <PdfName>(PdfName.RoleMapNS); PdfDocument toDocument = copyingParams.GetToDocument(); PdfDictionary copiedNsDict = srcNsDict.CopyTo(toDocument, excludeKeys, false); copyingParams.AddCopiedNamespace(copiedNsDict); PdfDictionary srcRoleMapNs = srcNsDict.GetAsDictionary(PdfName.RoleMapNS); // if this src namespace was already copied (or in the process of copying) it will contain role map already PdfDictionary copiedRoleMap = copiedNsDict.GetAsDictionary(PdfName.RoleMapNS); if (srcRoleMapNs != null && copiedRoleMap == null) { copiedRoleMap = new PdfDictionary(); copiedNsDict.Put(PdfName.RoleMapNS, copiedRoleMap); foreach (KeyValuePair <PdfName, PdfObject> entry in srcRoleMapNs.EntrySet()) { PdfObject copiedMapping; if (entry.Value.IsArray()) { PdfArray srcMappingArray = (PdfArray)entry.Value; if (srcMappingArray.Size() > 1 && srcMappingArray.Get(1).IsDictionary()) { PdfArray copiedMappingArray = new PdfArray(); copiedMappingArray.Add(srcMappingArray.Get(0).CopyTo(toDocument)); PdfDictionary copiedNamespace = CopyNamespaceDict(srcMappingArray.GetAsDictionary(1), copyingParams); copiedMappingArray.Add(copiedNamespace); copiedMapping = copiedMappingArray; } else { ILog logger = LogManager.GetLogger(typeof(StructureTreeCopier)); logger.Warn(String.Format(iText.IO.LogMessageConstant.ROLE_MAPPING_FROM_SOURCE_IS_NOT_COPIED_INVALID, entry .Key.ToString())); continue; } } else { copiedMapping = entry.Value.CopyTo(toDocument); } PdfName copiedRoleFrom = (PdfName)entry.Key.CopyTo(toDocument); copiedRoleMap.Put(copiedRoleFrom, copiedMapping); } } return(copiedNsDict); }
private static PdfDictionary CopyObject(PdfDictionary source, PdfDictionary destPage, bool parentChangePg, StructureTreeCopier.StructElemCopyingParams copyingParams) { PdfDictionary copied; if (copyingParams.IsCopyFromDestDocument()) { //TODO: detect wether object is needed to be cloned at all copied = source.Clone(ignoreKeysForClone); if (source.IsIndirect()) { copied.MakeIndirect(copyingParams.GetToDocument()); } PdfDictionary pg = source.GetAsDictionary(PdfName.Pg); if (pg != null) { if (copyingParams.IsCopyFromDestDocument()) { if (pg != destPage) { copied.Put(PdfName.Pg, destPage); parentChangePg = true; } else { parentChangePg = false; } } } } else { copied = source.CopyTo(copyingParams.GetToDocument(), ignoreKeysForCopy, true); PdfDictionary obj = source.GetAsDictionary(PdfName.Obj); if (obj != null) { // Link annotations could be not added to the toDocument, so we need to identify this case. // When obj.copyTo is called, and annotation was already copied, we would get this already created copy. // If it was already copied and added, /P key would be set. Otherwise /P won't be set. obj = obj.CopyTo(copyingParams.GetToDocument(), JavaUtil.ArraysAsList(PdfName.P), false); copied.Put(PdfName.Obj, obj); } PdfDictionary nsDict = source.GetAsDictionary(PdfName.NS); if (nsDict != null) { PdfDictionary copiedNsDict = CopyNamespaceDict(nsDict, copyingParams); copied.Put(PdfName.NS, copiedNsDict); } PdfDictionary pg = source.GetAsDictionary(PdfName.Pg); if (pg != null) { PdfDictionary pageAnalog = copyingParams.GetPage2page().Get(pg); if (pageAnalog == null) { pageAnalog = destPage; parentChangePg = true; } else { parentChangePg = false; } copied.Put(PdfName.Pg, pageAnalog); } } PdfObject k = source.Get(PdfName.K); if (k != null) { if (k.IsArray()) { PdfArray kArr = (PdfArray)k; PdfArray newArr = new PdfArray(); for (int i = 0; i < kArr.Size(); i++) { PdfObject copiedKid = CopyObjectKid(kArr.Get(i), copied, destPage, parentChangePg, copyingParams); if (copiedKid != null) { newArr.Add(copiedKid); } } if (!newArr.IsEmpty()) { if (newArr.Size() == 1) { copied.Put(PdfName.K, newArr.Get(0)); } else { copied.Put(PdfName.K, newArr); } } } else { PdfObject copiedKid = CopyObjectKid(k, copied, destPage, parentChangePg, copyingParams); if (copiedKid != null) { copied.Put(PdfName.K, copiedKid); } } } return(copied); }