예제 #1
0
        /// <summary>Removes the page at the specified position in this tree.</summary>
        /// <remarks>
        /// Removes the page at the specified position in this tree.
        /// Shifts any subsequent elements to the left (subtracts one from their
        /// indices).
        /// </remarks>
        /// <param name="pageNum">the one-based index of the PdfPage to be removed</param>
        /// <returns>the page that was removed from the list</returns>
        public virtual PdfPage RemovePage(int pageNum)
        {
            PdfPage pdfPage = GetPage(pageNum);

            if (pdfPage.IsFlushed())
            {
                LOGGER.Warn(iText.IO.LogMessageConstant.REMOVING_PAGE_HAS_ALREADY_BEEN_FLUSHED);
            }
            if (InternalRemovePage(--pageNum))
            {
                return(pdfPage);
            }
            else
            {
                return(null);
            }
        }
예제 #2
0
        /// <summary>Removes the page at the specified position in this tree.</summary>
        /// <remarks>
        /// Removes the page at the specified position in this tree.
        /// Shifts any subsequent elements to the left (subtracts one from their
        /// indices).
        /// </remarks>
        /// <param name="pageNum">the one-based index of the PdfPage to be removed</param>
        /// <returns>the page that was removed from the list</returns>
        public virtual PdfPage RemovePage(int pageNum)
        {
            PdfPage pdfPage = GetPage(pageNum);

            if (pdfPage.IsFlushed())
            {
                ILogger logger = LoggerFactory.GetLogger(typeof(PdfPage));
                logger.Warn(LogMessageConstant.REMOVING_PAGE_HAS_ALREADY_BEEN_FLUSHED);
            }
            if (InternalRemovePage(--pageNum))
            {
                return(pdfPage);
            }
            else
            {
                return(null);
            }
        }
        private bool FlushPage(int pageNum)
        {
            PdfPage page = pdfDoc.GetPage(pageNum);

            if (page.IsFlushed())
            {
                return(false);
            }
            bool pageChanged = false;

            if (!release)
            {
                pdfDoc.DispatchEvent(new PdfDocumentEvent(PdfDocumentEvent.END_PAGE, page));
                InitCurrentLayers(pdfDoc);
            }
            PdfDictionary pageDict = page.GetPdfObject();
            // Using PdfPage package internal methods in order to avoid PdfResources initialization: initializing PdfResources
            // limits processing possibilities only to cases in which resources and specific resource type dictionaries are not flushed.
            PdfDictionary resourcesDict = page.InitResources(false);
            // inits /Resources dict entry if not inherited and not created yet
            PdfResources resources = page.GetResources(false);

            if (resources != null && resources.IsModified() && !resources.IsReadOnly())
            {
                resourcesDict = resources.GetPdfObject();
                pageDict.Put(PdfName.Resources, resources.GetPdfObject());
                pageDict.SetModified();
                pageChanged = true;
            }
            if (!resourcesDict.IsFlushed())
            {
                FlushDictRecursively(resourcesDict, null);
                FlushOrRelease(resourcesDict);
            }
            FlushDictRecursively(pageDict, pageContext);
            if (release)
            {
                if (!page.GetPdfObject().IsModified())
                {
                    pdfDoc.GetCatalog().GetPageTree().ReleasePage(pageNum);
                    page.UnsetForbidRelease();
                    page.GetPdfObject().Release();
                }
            }
            else
            {
                if (pdfDoc.IsTagged() && !pdfDoc.GetStructTreeRoot().IsFlushed())
                {
                    page.TryFlushPageTags();
                }
                if (!pdfDoc.IsAppendMode() || page.GetPdfObject().IsModified())
                {
                    page.ReleaseInstanceFields();
                    page.GetPdfObject().Flush();
                }
                else
                {
                    // it's append mode
                    pdfDoc.GetCatalog().GetPageTree().ReleasePage(pageNum);
                    page.UnsetForbidRelease();
                    page.GetPdfObject().Release();
                }
            }
            layersRefs.Clear();
            return(pageChanged);
        }
        /// <summary>
        /// Flushes to the output stream modified objects that can belong only to the given page, which makes this method
        /// "safe" compared to the
        /// <see cref="UnsafeFlushDeep(int)"/>
        /// . Flushed object frees the memory, but it's impossible to
        /// modify such objects or read data from them. This method releases all other page structure objects that are not
        /// modified.
        /// <p>
        /// This method is mainly designed for the append mode. It is similar to the
        /// <see cref="PdfPage.Flush()"/>
        /// , but it
        /// additionally releases all page objects that were not flushed. This method is ideal for small amendments of pages,
        /// but it makes more sense to use
        /// <see cref="PdfPage.Flush()"/>
        /// for newly created or heavily modified pages. <br />
        /// This method will throw an exception for documents opened in reading mode (see
        /// <see cref="PageFlushingHelper"/>
        /// for more details on modes). It is also not advised to be used in stamping mode: even though it will indeed
        /// release the objects and free the memory, the released objects will definitely be re-read again on document
        /// closing, which would affect performance.
        /// </p>
        /// <p>
        /// When using this method in append mode (or in stamping mode), be careful not to try to modify the object instances
        /// obtained before this method call! See
        /// <see cref="PageFlushingHelper"/>
        /// for details on released and flushed objects state.
        /// </p>
        /// <p>
        /// This method shall be used only when it's known that the page and its inner structures processing is finished.
        /// This includes reading data from pages, page modification and page handling via addons/utilities.
        /// </p>
        /// </summary>
        /// <param name="pageNum">the page number which low level objects structure is to be flushed or released from memory.
        ///     </param>
        public virtual void AppendModeFlush(int pageNum)
        {
            if (pdfDoc.GetWriter() == null)
            {
                throw new ArgumentException(PdfException.FlushingHelperFLushingModeIsNotForDocReadingMode);
            }
            PdfPage page = pdfDoc.GetPage(pageNum);

            if (page.IsFlushed())
            {
                return;
            }
            page.GetDocument().DispatchEvent(new PdfDocumentEvent(PdfDocumentEvent.END_PAGE, page));
            bool pageWasModified = page.GetPdfObject().IsModified();

            page.SetModified();
            release         = true;
            pageWasModified = FlushPage(pageNum) || pageWasModified;
            PdfArray annots = page.GetPdfObject().GetAsArray(PdfName.Annots);

            if (annots != null && !annots.IsFlushed())
            {
                ArrayFlushIfModified(annots);
            }
            PdfObject thumb = page.GetPdfObject().Get(PdfName.Thumb, false);

            FlushIfModified(thumb);
            PdfObject contents = page.GetPdfObject().Get(PdfName.Contents, false);

            if (contents is PdfIndirectReference)
            {
                if (contents.CheckState(PdfObject.MODIFIED) && !contents.CheckState(PdfObject.FLUSHED))
                {
                    PdfObject contentsDirectObj = ((PdfIndirectReference)contents).GetRefersTo();
                    if (contentsDirectObj.IsArray())
                    {
                        ArrayFlushIfModified((PdfArray)contentsDirectObj);
                    }
                    else
                    {
                        contentsDirectObj.Flush();
                    }
                }
            }
            else
            {
                // already checked that modified
                if (contents is PdfArray)
                {
                    ArrayFlushIfModified((PdfArray)contents);
                }
                else
                {
                    if (contents is PdfStream)
                    {
                        FlushIfModified(contents);
                    }
                }
            }
            // Page tags flushing is supported only in PdfPage#flush and #unsafeFlushDeep: it makes sense to flush tags
            // completely for heavily modified or new pages. For the slightly modified pages it should be enough to release
            // the tag structure objects via tag structure releasing utility.
            if (!pageWasModified)
            {
                page.GetPdfObject().GetIndirectReference().ClearState(PdfObject.MODIFIED);
                pdfDoc.GetCatalog().GetPageTree().ReleasePage(pageNum);
                page.UnsetForbidRelease();
                page.GetPdfObject().Release();
            }
            else
            {
                // inherited and modified resources are handled in #flushPage call in the beginning of method
                page.ReleaseInstanceFields();
                page.GetPdfObject().Flush();
            }
        }