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); }
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; } }
/// <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]); }
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); }
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; }
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(); } }
/// <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); }
public virtual PdfMcr AddKid(PdfMcr kid) { return(AddKid(-1, kid)); }
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(); } } } }
public virtual void RegisterMcr(PdfMcr mcr) { RegisterMcr(mcr, false); }
internal virtual void PutObjectReferenceMcr(int structParentIndex, PdfMcr mcr) { objRefs.Put(structParentIndex, mcr); }
/// <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]); }