Ejemplo n.º 1
0
        private void RegisterAllMcrs()
        {
            pageToPageMcrs = new Dictionary <PdfIndirectReference, SortedDictionary <int, PdfMcr> >();
            // we create new number tree and not using parentTree, because we want parentTree to be empty
            IDictionary <int?, PdfObject> parentTreeEntries = new PdfNumTree(structTreeRoot.GetDocument().GetCatalog(),
                                                                             PdfName.ParentTree).GetNumbers();
            ICollection <PdfStructElem> mcrParents = new HashSet <PdfStructElem>();
            int maxStructParentIndex = -1;

            foreach (KeyValuePair <int?, PdfObject> entry in parentTreeEntries)
            {
                if (entry.Key > maxStructParentIndex)
                {
                    maxStructParentIndex = (int)entry.Key;
                }
                PdfObject entryValue = entry.Value;
                if (entryValue.IsDictionary())
                {
                    mcrParents.Add(new PdfStructElem((PdfDictionary)entryValue));
                }
                else
                {
                    if (entryValue.IsArray())
                    {
                        PdfArray parentsArray = (PdfArray)entryValue;
                        for (int i = 0; i < parentsArray.Size(); ++i)
                        {
                            PdfDictionary parent = parentsArray.GetAsDictionary(i);
                            if (parent != null)
                            {
                                mcrParents.Add(new PdfStructElem(parent));
                            }
                        }
                    }
                }
            }
            structTreeRoot.GetPdfObject().Put(PdfName.ParentTreeNextKey, new PdfNumber(maxStructParentIndex + 1));
            foreach (PdfStructElem mcrParent in mcrParents)
            {
                foreach (IStructureNode kid in mcrParent.GetKids())
                {
                    if (kid is PdfMcr)
                    {
                        RegisterMcr((PdfMcr)kid, true);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <returns>parent of the current structure element. Returns null if parent isn't set or if either current element or parent are invalid.
        ///     </returns>
        public virtual IStructureNode GetParent()
        {
            PdfDictionary parent = GetPdfObject().GetAsDictionary(PdfName.P);

            if (parent == null)
            {
                return(null);
            }
            if (parent.IsFlushed())
            {
                PdfDocument pdfDoc = GetDocument();
                if (pdfDoc == null)
                {
                    return(null);
                }
                PdfStructTreeRoot structTreeRoot = pdfDoc.GetStructTreeRoot();
                return(structTreeRoot.GetPdfObject() == parent ? (IStructureNode)structTreeRoot : new iText.Kernel.Pdf.Tagging.PdfStructElem
                           (parent));
            }
            if (IsStructElem(parent))
            {
                return(new iText.Kernel.Pdf.Tagging.PdfStructElem(parent));
            }
            else
            {
                PdfDocument pdfDoc       = GetDocument();
                bool        parentIsRoot = pdfDoc != null && PdfName.StructTreeRoot.Equals(parent.GetAsName(PdfName.Type));
                parentIsRoot = parentIsRoot || pdfDoc != null && pdfDoc.GetStructTreeRoot().GetPdfObject() == parent;
                if (parentIsRoot)
                {
                    return(pdfDoc.GetStructTreeRoot());
                }
                else
                {
                    return(null);
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Copies structure to a
        /// <paramref name="destDocument"/>
        /// and insert it in a specified position in the document.
        /// <br/><br/>
        /// NOTE: Works only for
        /// <c>PdfStructTreeRoot</c>
        /// that is read from the document opened in reading mode,
        /// otherwise an exception is thrown.
        /// <br/>
        /// Also, to insert a tagged page into existing tag structure, existing tag structure shouldn't be flushed, otherwise
        /// an exception may be raised.
        /// </summary>
        /// <param name="destDocument">document to copy structure to.</param>
        /// <param name="insertBeforePage">indicates where the structure to be inserted.</param>
        /// <param name="page2page">association between original page and copied page.</param>
        public static void CopyTo(PdfDocument destDocument, int insertBeforePage, IDictionary <PdfPage, PdfPage> page2page
                                  , PdfDocument callingDocument)
        {
            if (!destDocument.IsTagged())
            {
                return;
            }
            // Here we separate the structure tree in two parts: struct elems that belong to the pages which indexes are
            // less then insertBeforePage and those struct elems that belong to other pages. Some elems might belong
            // to both parts and actually these are the ones that we are looking for.
            ICollection <PdfObject> firstPartElems     = new HashSet <PdfObject>();
            PdfStructTreeRoot       destStructTreeRoot = destDocument.GetStructTreeRoot();

            for (int i = 1; i < insertBeforePage; ++i)
            {
                PdfPage pageOfFirstHalf       = destDocument.GetPage(i);
                ICollection <PdfMcr> pageMcrs = destStructTreeRoot.GetPageMarkedContentReferences(pageOfFirstHalf);
                if (pageMcrs != null)
                {
                    foreach (PdfMcr mcr in pageMcrs)
                    {
                        firstPartElems.Add(mcr.GetPdfObject());
                        PdfDictionary top = AddAllParentsToSet(mcr, firstPartElems);
                        if (top.IsFlushed())
                        {
                            throw new PdfException(PdfException.TagFromTheExistingTagStructureIsFlushedCannotAddCopiedPageTags);
                        }
                    }
                }
            }
            IList <PdfDictionary> clonedTops = new List <PdfDictionary>();
            PdfArray tops = destStructTreeRoot.GetKidsObject();
            // Now we "walk" through all the elems which belong to the first part, and look for the ones that contain both
            // kids from first and second part. We clone found elements and move kids from the second part to cloned elems.
            int lastTopBefore = 0;

            for (int i_1 = 0; i_1 < tops.Size(); ++i_1)
            {
                PdfDictionary top = tops.GetAsDictionary(i_1);
                if (firstPartElems.Contains(top))
                {
                    lastTopBefore = i_1;
                    StructureTreeCopier.LastClonedAncestor lastCloned = new StructureTreeCopier.LastClonedAncestor();
                    lastCloned.ancestor = top;
                    PdfDictionary topClone = top.Clone(ignoreKeysForClone);
                    topClone.Put(PdfName.P, destStructTreeRoot.GetPdfObject());
                    lastCloned.clone = topClone;
                    SeparateKids(top, firstPartElems, lastCloned);
                    if (topClone.ContainsKey(PdfName.K))
                    {
                        topClone.MakeIndirect(destDocument);
                        clonedTops.Add(topClone);
                    }
                }
            }
            for (int i_2 = 0; i_2 < clonedTops.Count; ++i_2)
            {
                destStructTreeRoot.AddKidObject(lastTopBefore + 1 + i_2, clonedTops[i_2]);
            }
            CopyTo(destDocument, page2page, callingDocument, false, lastTopBefore + 1);
        }