private void UpdateStructParentTreeEntries(int?pageStructParentIndex, IDictionary <int, PdfMcr> mcrs)
        {
            // element indexes in parentsOfPageMcrs shall be the same as mcid of one of their kids.
            // See "Finding Structure Elements from Content Items" in pdf spec.
            PdfArray parentsOfPageMcrs = new PdfArray();
            int      currentMcid       = 0;

            foreach (KeyValuePair <int, PdfMcr> entry in mcrs)
            {
                PdfMcr mcr = entry.Value;
                if (mcr is PdfObjRef)
                {
                    int structParent = KeyIntoStructParentIndex((int)entry.Key);
                    parentTree.AddEntry(structParent, ((PdfStructElem)mcr.GetParent()).GetPdfObject());
                }
                else
                {
                    // if for some reason some mcr where not registered or don't exist, we ensure that the rest
                    // of the parent objects were placed at correct index
                    while (currentMcid++ < mcr.GetMcid())
                    {
                        parentsOfPageMcrs.Add(PdfNull.PDF_NULL);
                    }
                    parentsOfPageMcrs.Add(((PdfStructElem)mcr.GetParent()).GetPdfObject());
                }
            }
            if (parentsOfPageMcrs.Size() > 0)
            {
                parentsOfPageMcrs.MakeIndirect(structTreeRoot.GetDocument());
                parentTree.AddEntry(pageStructParentIndex, parentsOfPageMcrs);
                structTreeRoot.GetDocument().CheckIsoConformance(parentsOfPageMcrs, IsoKey.TAG_STRUCTURE_ELEMENT);
                parentsOfPageMcrs.Flush();
            }
        }
        private bool UpdateStructParentTreeForContentStreamEntries(IDictionary <int, PdfMcr> mcrsOfContentStream, int
                                                                   pageStructParentIndex)
        {
            // element indices in parentsOfMcrs shall be the same as mcid of one of their kids.
            // See "Finding Structure Elements from Content Items" in pdf spec.
            PdfArray parentsOfMcrs = new PdfArray();
            int      currentMcid   = 0;

            foreach (KeyValuePair <int, PdfMcr> entry in mcrsOfContentStream)
            {
                PdfMcr        mcr       = entry.Value;
                PdfDictionary parentObj = ((PdfStructElem)mcr.GetParent()).GetPdfObject();
                if (!parentObj.IsIndirect())
                {
                    continue;
                }
                // if for some reason some mcrs were not registered or don't exist, we ensure that the rest
                // of the parent objects were placed at correct index
                while (currentMcid++ < mcr.GetMcid())
                {
                    parentsOfMcrs.Add(PdfNull.PDF_NULL);
                }
                parentsOfMcrs.Add(parentObj);
            }
            if (!parentsOfMcrs.IsEmpty())
            {
                parentsOfMcrs.MakeIndirect(structTreeRoot.GetDocument());
                parentTree.AddEntry(pageStructParentIndex, parentsOfMcrs);
                structTreeRoot.GetDocument().CheckIsoConformance(parentsOfMcrs, IsoKey.TAG_STRUCTURE_ELEMENT);
                parentsOfMcrs.Flush();
                return(true);
            }
            return(false);
        }
Exemple #3
0
        public virtual void RegisterMcr(PdfMcr mcr)
        {
            SortedDictionary <int, PdfMcr> pageMcrs = pageToPageMcrs.Get(mcr.GetPageObject().GetIndirectReference());

            if (pageMcrs == null)
            {
                pageMcrs = new SortedDictionary <int, PdfMcr>();
                pageToPageMcrs[mcr.GetPageObject().GetIndirectReference()] = pageMcrs;
            }
            if (mcr is PdfObjRef)
            {
                PdfDictionary obj = ((PdfDictionary)mcr.GetPdfObject()).GetAsDictionary(PdfName.Obj);
                if (obj == null || obj.IsFlushed())
                {
                    throw new PdfException(PdfException.WhenAddingObjectReferenceToTheTagTreeItMustBeConnectedToNotFlushedObject
                                           );
                }
                PdfNumber n = obj.GetAsNumber(PdfName.StructParent);
                if (n != null)
                {
                    pageMcrs[StructParentIndexIntoKey(n.IntValue())] = mcr;
                }
                else
                {
                    throw new PdfException(PdfException.StructParentIndexNotFoundInTaggedObject);
                }
            }
            else
            {
                pageMcrs[mcr.GetMcid()] = mcr;
            }
        }
Exemple #4
0
        /// <returns>the topmost parent added to set. If encountered flushed element - stops and returns this flushed element.
        ///     </returns>
        private static PdfDictionary AddAllParentsToSet(PdfMcr mcr, ICollection <PdfObject> set)
        {
            IList <PdfDictionary> allParents = RetrieveParents(mcr, true);

            set.AddAll(allParents);
            return(allParents.IsEmpty() ? null : allParents[allParents.Count - 1]);
        }
Exemple #5
0
        private bool UpdateStructParentTreeEntries(PdfPage page, IDictionary <int, PdfMcr> mcrs)
        {
            bool res = false;
            // element indexes in parentsOfPageMcrs shall be the same as mcid of one of their kids.
            // See "Finding Structure Elements from Content Items" in pdf spec.
            PdfArray parentsOfPageMcrs = new PdfArray();
            int      currentMcid       = 0;

            foreach (KeyValuePair <int, PdfMcr> entry in mcrs)
            {
                PdfMcr        mcr       = entry.Value;
                PdfDictionary parentObj = ((PdfStructElem)mcr.GetParent()).GetPdfObject();
                if (!parentObj.IsIndirect())
                {
                    continue;
                }
                if (mcr is PdfObjRef)
                {
                    int structParent = KeyIntoStructParentIndex((int)entry.Key);
                    parentTree.AddEntry(structParent, parentObj);
                    res = true;
                }
                else
                {
                    // if for some reason some mcr where not registered or don't exist, we ensure that the rest
                    // of the parent objects were placed at correct index
                    while (currentMcid++ < mcr.GetMcid())
                    {
                        parentsOfPageMcrs.Add(PdfNull.PDF_NULL);
                    }
                    parentsOfPageMcrs.Add(parentObj);
                }
            }
            if (!parentsOfPageMcrs.IsEmpty())
            {
                int pageStructParentIndex;
                if (page.IsFlushed())
                {
                    PdfIndirectReference pageRef = page.GetPdfObject().GetIndirectReference();
                    if (!pageToStructParentsInd.ContainsKey(pageRef))
                    {
                        return(res);
                    }
                    pageStructParentIndex = (int)pageToStructParentsInd.JRemove(pageRef);
                }
                else
                {
                    pageStructParentIndex = GetOrCreatePageStructParentIndex(page);
                }
                parentsOfPageMcrs.MakeIndirect(structTreeRoot.GetDocument());
                parentTree.AddEntry(pageStructParentIndex, parentsOfPageMcrs);
                res = true;
                structTreeRoot.GetDocument().CheckIsoConformance(parentsOfPageMcrs, IsoKey.TAG_STRUCTURE_ELEMENT);
                parentsOfPageMcrs.Flush();
            }
            return(res);
        }
            internal virtual void PutXObjectMcr(PdfIndirectReference xObjectIndRef, PdfMcr mcr)
            {
                SortedDictionary <int, PdfMcr> xObjectMcrs = pageResourceXObjects.Get(xObjectIndRef);

                if (xObjectMcrs == null)
                {
                    xObjectMcrs = new SortedDictionary <int, PdfMcr>();
                    pageResourceXObjects.Put(xObjectIndRef, xObjectMcrs);
                }
                pageResourceXObjects.Get(xObjectIndRef).Put(mcr.GetMcid(), mcr);
            }
 private static PdfObject GetStm(PdfMcr mcr)
 {
     /*
      * Presence of Stm guarantees that the mcr belongs to XObject, absence of Stm guarantees that the mcr belongs to page content stream.
      * See 14.7.4.2 Marked-Content Sequences as Content Items, Table 324 – Entries in a marked-content reference dictionary.
      */
     if (mcr is PdfMcrDictionary)
     {
         return(((PdfDictionary)mcr.GetPdfObject()).Get(PdfName.Stm, false));
     }
     return(null);
 }
        private bool UpdateStructParentTreeEntries(PdfPage page, ParentTreeHandler.PageMcrsContainer mcrs)
        {
            bool res = false;

            foreach (KeyValuePair <int, PdfMcr> entry in mcrs.GetObjRefs())
            {
                PdfMcr        mcr       = entry.Value;
                PdfDictionary parentObj = ((PdfStructElem)mcr.GetParent()).GetPdfObject();
                if (!parentObj.IsIndirect())
                {
                    continue;
                }
                int structParent = entry.Key;
                parentTree.AddEntry(structParent, parentObj);
                res = true;
            }
            int pageStructParentIndex;

            foreach (KeyValuePair <PdfIndirectReference, SortedDictionary <int, PdfMcr> > entry in mcrs.GetPageResourceXObjects
                         ())
            {
                PdfIndirectReference xObjectRef = entry.Key;
                if (xObjectToStructParentsInd.ContainsKey(xObjectRef))
                {
                    pageStructParentIndex = (int)xObjectToStructParentsInd.JRemove(xObjectRef);
                    if (UpdateStructParentTreeForContentStreamEntries(entry.Value, pageStructParentIndex))
                    {
                        res = true;
                    }
                }
            }
            if (page.IsFlushed())
            {
                PdfIndirectReference pageRef = page.GetPdfObject().GetIndirectReference();
                if (!pageToStructParentsInd.ContainsKey(pageRef))
                {
                    return(res);
                }
                pageStructParentIndex = (int)pageToStructParentsInd.JRemove(pageRef);
            }
            else
            {
                pageStructParentIndex = GetOrCreatePageStructParentIndex(page);
            }
            if (UpdateStructParentTreeForContentStreamEntries(mcrs.GetPageContentStreamsMcrs(), pageStructParentIndex)
                )
            {
                res = true;
            }
            return(res);
        }
Exemple #9
0
        public virtual void UnregisterMcr(PdfMcr mcrToUnregister)
        {
            PdfDictionary pageDict = mcrToUnregister.GetPageObject();

            if (pageDict == null)
            {
                // invalid mcr, ignore
                return;
            }
            if (pageDict.IsFlushed())
            {
                throw new PdfException(PdfException.CannotRemoveMarkedContentReferenceBecauseItsPageWasAlreadyFlushed);
            }
            IDictionary <int, PdfMcr> pageMcrs = pageToPageMcrs.Get(pageDict.GetIndirectReference());

            if (pageMcrs != null)
            {
                if (mcrToUnregister is PdfObjRef)
                {
                    PdfDictionary obj = ((PdfDictionary)mcrToUnregister.GetPdfObject()).GetAsDictionary(PdfName.Obj);
                    if (obj != null && !obj.IsFlushed())
                    {
                        PdfNumber n = obj.GetAsNumber(PdfName.StructParent);
                        if (n != null)
                        {
                            pageMcrs.JRemove(StructParentIndexIntoKey(n.IntValue()));
                            structTreeRoot.SetModified();
                            return;
                        }
                    }
                    foreach (KeyValuePair <int, PdfMcr> entry in pageMcrs)
                    {
                        if (entry.Value.GetPdfObject() == mcrToUnregister.GetPdfObject())
                        {
                            pageMcrs.JRemove(entry.Key);
                            structTreeRoot.SetModified();
                            break;
                        }
                    }
                }
                else
                {
                    pageMcrs.JRemove(mcrToUnregister.GetMcid());
                    structTreeRoot.SetModified();
                }
            }
        }
 public virtual int RemoveKid(IPdfStructElem kid)
 {
     if (kid is PdfMcr)
     {
         PdfMcr mcr = (PdfMcr)kid;
         GetDocument().GetStructTreeRoot().GetParentTreeHandler().UnregisterMcr(mcr);
         return(RemoveKidObject(mcr.GetPdfObject()));
     }
     else
     {
         if (kid is iText.Kernel.Pdf.Tagging.PdfStructElem)
         {
             return(RemoveKidObject(((iText.Kernel.Pdf.Tagging.PdfStructElem)kid).GetPdfObject()));
         }
     }
     return(-1);
 }
 private static IList<PdfDictionary> RetrieveParents(PdfMcr mcr, bool all) {
     IList<PdfDictionary> parents = new List<PdfDictionary>();
     IStructureNode firstParent = mcr.GetParent();
     PdfDictionary previous = null;
     PdfDictionary current = firstParent is PdfStructElem ? ((PdfStructElem)firstParent).GetPdfObject() : null;
     while (current != null && !PdfName.StructTreeRoot.Equals(current.GetAsName(PdfName.Type))) {
         if (all) {
             parents.Add(current);
         }
         previous = current;
         current = previous.IsFlushed() ? null : previous.GetAsDictionary(PdfName.P);
     }
     if (!all) {
         parents.Add(previous);
     }
     return parents;
 }
Exemple #12
0
        private void RegisterMcr(PdfMcr mcr, bool registeringOnInit)
        {
            PdfDictionary mcrPageObject = mcr.GetPageObject();

            if (mcrPageObject == null || (!(mcr is PdfObjRef) && mcr.GetMcid() < 0))
            {
                ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.Tagging.ParentTreeHandler));
                logger.Error(iText.IO.LogMessageConstant.ENCOUNTERED_INVALID_MCR);
                return;
            }
            SortedDictionary <int, PdfMcr> pageMcrs = pageToPageMcrs.Get(mcrPageObject.GetIndirectReference());

            if (pageMcrs == null)
            {
                pageMcrs = new SortedDictionary <int, PdfMcr>();
                pageToPageMcrs.Put(mcrPageObject.GetIndirectReference(), pageMcrs);
            }
            if (mcr is PdfObjRef)
            {
                PdfDictionary obj = ((PdfDictionary)mcr.GetPdfObject()).GetAsDictionary(PdfName.Obj);
                if (obj == null || obj.IsFlushed())
                {
                    throw new PdfException(PdfException.WhenAddingObjectReferenceToTheTagTreeItMustBeConnectedToNotFlushedObject
                                           );
                }
                PdfNumber n = obj.GetAsNumber(PdfName.StructParent);
                if (n != null)
                {
                    pageMcrs.Put(StructParentIndexIntoKey(n.IntValue()), mcr);
                }
                else
                {
                    throw new PdfException(PdfException.StructParentIndexNotFoundInTaggedObject);
                }
            }
            else
            {
                pageMcrs.Put(mcr.GetMcid(), mcr);
            }
            if (!registeringOnInit)
            {
                structTreeRoot.SetModified();
            }
        }
Exemple #13
0
        /// <returns>the topmost parent added to set. If encountered flushed element - stops and returns this flushed element.
        ///     </returns>
        private static PdfDictionary AddAllParentsToSet(PdfMcr mcr, ICollection <PdfObject> set)
        {
            PdfDictionary elem = ((PdfStructElem)mcr.GetParent()).GetPdfObject();

            set.Add(elem);
            for (; ;)
            {
                if (elem.IsFlushed())
                {
                    break;
                }
                PdfDictionary p = elem.GetAsDictionary(PdfName.P);
                if (p == null || PdfName.StructTreeRoot.Equals(p.GetAsName(PdfName.Type)))
                {
                    break;
                }
                else
                {
                    elem = p;
                    set.Add(elem);
                }
            }
            return(elem);
        }
 internal virtual void PutPageContentStreamMcr(int mcid, PdfMcr mcr)
 {
     pageContentStreams.Put(mcid, mcr);
 }
Exemple #15
0
 public virtual PdfMcr AddKid(PdfMcr kid)
 {
     return(AddKid(-1, kid));
 }
Exemple #16
0
 public virtual PdfMcr AddKid(int index, PdfMcr kid)
 {
     GetDocEnsureIndirectForKids().GetStructTreeRoot().GetParentTreeHandler().RegisterMcr(kid);
     AddKidObject(GetPdfObject(), index, kid.GetPdfObject());
     return(kid);
 }
        private void RegisterMcr(PdfMcr mcr, bool registeringOnInit)
        {
            PdfIndirectReference mcrPageIndRef = mcr.GetPageIndirectReference();

            if (mcrPageIndRef == null || (!(mcr is PdfObjRef) && mcr.GetMcid() < 0))
            {
                ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.Tagging.ParentTreeHandler));
                logger.Error(iText.IO.LogMessageConstant.ENCOUNTERED_INVALID_MCR);
                return;
            }
            ParentTreeHandler.PageMcrsContainer pageMcrs = pageToPageMcrs.Get(mcrPageIndRef);
            if (pageMcrs == null)
            {
                pageMcrs = new ParentTreeHandler.PageMcrsContainer();
                pageToPageMcrs.Put(mcrPageIndRef, pageMcrs);
            }
            PdfObject stm;

            if ((stm = GetStm(mcr)) != null)
            {
                PdfIndirectReference stmIndRef;
                PdfStream            xObjectStream;
                if (stm is PdfIndirectReference)
                {
                    stmIndRef     = (PdfIndirectReference)stm;
                    xObjectStream = (PdfStream)stmIndRef.GetRefersTo();
                }
                else
                {
                    if (stm.GetIndirectReference() == null)
                    {
                        stm.MakeIndirect(structTreeRoot.GetDocument());
                    }
                    stmIndRef     = stm.GetIndirectReference();
                    xObjectStream = (PdfStream)stm;
                }
                int?structParent = xObjectStream.GetAsInt(PdfName.StructParents);
                if (structParent != null)
                {
                    xObjectToStructParentsInd.Put(stmIndRef, structParent);
                }
                else
                {
                    // TODO DEVSIX-3351 an error is thrown here because right now no /StructParents will be created.
                    ILog logger = LogManager.GetLogger(typeof(iText.Kernel.Pdf.Tagging.ParentTreeHandler));
                    logger.Error(iText.IO.LogMessageConstant.XOBJECT_HAS_NO_STRUCT_PARENTS);
                }
                pageMcrs.PutXObjectMcr(stmIndRef, mcr);
                if (registeringOnInit)
                {
                    xObjectStream.Release();
                }
            }
            else
            {
                if (mcr is PdfObjRef)
                {
                    PdfDictionary obj = ((PdfDictionary)mcr.GetPdfObject()).GetAsDictionary(PdfName.Obj);
                    if (obj == null || obj.IsFlushed())
                    {
                        throw new PdfException(PdfException.WhenAddingObjectReferenceToTheTagTreeItMustBeConnectedToNotFlushedObject
                                               );
                    }
                    PdfNumber n = obj.GetAsNumber(PdfName.StructParent);
                    if (n != null)
                    {
                        pageMcrs.PutObjectReferenceMcr(n.IntValue(), mcr);
                    }
                    else
                    {
                        throw new PdfException(PdfException.StructParentIndexNotFoundInTaggedObject);
                    }
                }
                else
                {
                    pageMcrs.PutPageContentStreamMcr(mcr.GetMcid(), mcr);
                }
            }
            if (!registeringOnInit)
            {
                structTreeRoot.SetModified();
            }
        }
        public virtual void UnregisterMcr(PdfMcr mcrToUnregister)
        {
            PdfDictionary pageDict = mcrToUnregister.GetPageObject();

            if (pageDict == null)
            {
                // invalid mcr, ignore
                return;
            }
            if (pageDict.IsFlushed())
            {
                throw new PdfException(PdfException.CannotRemoveMarkedContentReferenceBecauseItsPageWasAlreadyFlushed);
            }
            ParentTreeHandler.PageMcrsContainer pageMcrs = pageToPageMcrs.Get(pageDict.GetIndirectReference());
            if (pageMcrs != null)
            {
                PdfObject stm;
                if ((stm = GetStm(mcrToUnregister)) != null)
                {
                    PdfIndirectReference xObjectReference = stm is PdfIndirectReference ? (PdfIndirectReference)stm : stm.GetIndirectReference
                                                                ();
                    pageMcrs.GetPageResourceXObjects().Get(xObjectReference).JRemove(mcrToUnregister.GetMcid());
                    if (pageMcrs.GetPageResourceXObjects().Get(xObjectReference).IsEmpty())
                    {
                        pageMcrs.GetPageResourceXObjects().JRemove(xObjectReference);
                        xObjectToStructParentsInd.JRemove(xObjectReference);
                    }
                    structTreeRoot.SetModified();
                }
                else
                {
                    if (mcrToUnregister is PdfObjRef)
                    {
                        PdfDictionary obj = ((PdfDictionary)mcrToUnregister.GetPdfObject()).GetAsDictionary(PdfName.Obj);
                        if (obj != null && !obj.IsFlushed())
                        {
                            PdfNumber n = obj.GetAsNumber(PdfName.StructParent);
                            if (n != null)
                            {
                                pageMcrs.GetObjRefs().JRemove(n.IntValue());
                                structTreeRoot.SetModified();
                                return;
                            }
                        }
                        foreach (KeyValuePair <int, PdfMcr> entry in pageMcrs.GetObjRefs())
                        {
                            if (entry.Value.GetPdfObject() == mcrToUnregister.GetPdfObject())
                            {
                                pageMcrs.GetObjRefs().JRemove(entry.Key);
                                structTreeRoot.SetModified();
                                break;
                            }
                        }
                    }
                    else
                    {
                        pageMcrs.GetPageContentStreamsMcrs().JRemove(mcrToUnregister.GetMcid());
                        structTreeRoot.SetModified();
                    }
                }
            }
        }
Exemple #19
0
 public virtual void RegisterMcr(PdfMcr mcr)
 {
     RegisterMcr(mcr, false);
 }
 internal virtual void PutObjectReferenceMcr(int structParentIndex, PdfMcr mcr)
 {
     objRefs.Put(structParentIndex, mcr);
 }
Exemple #21
0
 /// <summary>Gets the topmost non-root structure element parent.</summary>
 /// <remarks>Gets the topmost non-root structure element parent. May be flushed.</remarks>
 /// <param name="mcr">starting element</param>
 /// <returns>
 /// topmost non-root structure element parent, or
 /// <see langword="null"/>
 /// if it doesn't have any
 /// </returns>
 private static PdfDictionary GetTopmostParent(PdfMcr mcr)
 {
     return(RetrieveParents(mcr, false)[0]);
 }