コード例 #1
0
        // zero-based index
        private bool InternalRemovePage(int pageNum)
        {
            int      parentIndex = FindPageParent(pageNum);
            PdfPages pdfPages    = parents[parentIndex];

            if (pdfPages.RemovePage(pageNum))
            {
                if (pdfPages.GetCount() == 0)
                {
                    parents.JRemoveAt(parentIndex);
                    pdfPages.RemoveFromParent();
                    --parentIndex;
                }
                if (parents.Count == 0)
                {
                    root = null;
                    parents.Add(new PdfPages(0, document));
                }
                else
                {
                    CorrectPdfPagesFromProperty(parentIndex + 1, -1);
                }
                pageRefs.JRemoveAt(pageNum);
                pages.JRemoveAt(pageNum);
                return(true);
            }
            else
            {
                return(false);
            }
        }
コード例 #2
0
 /// <summary>Generate PdfPages tree.</summary>
 /// <returns>
 /// root
 /// <see cref="PdfPages"/>
 /// </returns>
 /// <exception cref="iText.Kernel.PdfException">in case empty document</exception>
 protected internal virtual PdfObject GenerateTree()
 {
     if (pageRefs.Count == 0)
     {
         throw new PdfException(PdfException.DocumentHasNoPages);
     }
     if (generated)
     {
         throw new PdfException(PdfException.PdfPagesTreeCouldBeGeneratedOnlyOnce);
     }
     if (root == null)
     {
         while (parents.Count != 1)
         {
             IList <PdfPages> nextParents = new List <PdfPages>();
             //dynamicLeafSize helps to avoid PdfPages leaf with only one page
             int      dynamicLeafSize = leafSize;
             PdfPages current         = null;
             for (int i = 0; i < parents.Count; i++)
             {
                 PdfPages pages     = parents[i];
                 int      pageCount = pages.GetCount();
                 if (i % dynamicLeafSize == 0)
                 {
                     if (pageCount <= 1)
                     {
                         dynamicLeafSize++;
                     }
                     else
                     {
                         current = new PdfPages(-1, document);
                         nextParents.Add(current);
                         dynamicLeafSize = leafSize;
                     }
                 }
                 System.Diagnostics.Debug.Assert(current != null);
                 current.AddPages(pages);
             }
             parents = nextParents;
         }
         root = parents[0];
     }
     generated = true;
     return(root.GetPdfObject());
 }
コード例 #3
0
        private void LoadPage(int pageNum)
        {
            PdfDictionary targetPage = pageRefs[pageNum];

            if (targetPage != null)
            {
                return;
            }
            //if we go here, we have to split PdfPages that contains pageNum
            int      parentIndex = FindPageParent(pageNum);
            PdfPages parent      = parents[parentIndex];
            PdfArray kids        = parent.GetKids();

            if (kids == null)
            {
                throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1);
            }
            int kidsCount = parent.GetCount();
            // we should handle separated pages, it means every PdfArray kids must contain either PdfPage or PdfPages,
            // mix of PdfPage and PdfPages not allowed.
            bool findPdfPages = false;

            // NOTE optimization? when we already found needed index
            for (int i = 0; i < kids.Size(); i++)
            {
                PdfDictionary page = kids.GetAsDictionary(i);
                if (page == null)
                {
                    // null values not allowed in pages tree.
                    throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1);
                }
                PdfObject pageKids = page.Get(PdfName.Kids);
                if (pageKids != null)
                {
                    if (pageKids.GetObjectType() == PdfObject.ARRAY)
                    {
                        findPdfPages = true;
                    }
                    else
                    {
                        // kids must be of type array
                        throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1);
                    }
                }
            }
            if (findPdfPages)
            {
                // handle mix of PdfPage and PdfPages.
                // handle count property!
                IList <PdfPages> newParents   = new List <PdfPages>(kids.Size());
                PdfPages         lastPdfPages = null;
                for (int i_1 = 0; i_1 < kids.Size() && kidsCount > 0; i_1++)
                {
                    PdfDictionary pdfPagesObject = kids.GetAsDictionary(i_1);
                    if (pdfPagesObject.GetAsArray(PdfName.Kids) == null)
                    {
                        // pdfPagesObject is PdfPage
                        if (lastPdfPages == null)
                        {
                            // possible if only first kid is PdfPage
                            lastPdfPages = new PdfPages(parent.GetFrom(), document, parent);
                            kids.Set(i_1, lastPdfPages.GetPdfObject());
                            newParents.Add(lastPdfPages);
                        }
                        lastPdfPages.AddPage(pdfPagesObject);
                        kids.Remove(i_1);
                        i_1--;
                        kidsCount--;
                    }
                    else
                    {
                        // pdfPagesObject is PdfPages
                        int from = lastPdfPages == null?parent.GetFrom() : lastPdfPages.GetFrom() + lastPdfPages.GetCount();

                        lastPdfPages = new PdfPages(from, kidsCount, pdfPagesObject, parent);
                        newParents.Add(lastPdfPages);
                        kidsCount -= lastPdfPages.GetCount();
                    }
                }
                parents.JRemoveAt(parentIndex);
                for (int i_2 = newParents.Count - 1; i_2 >= 0; i_2--)
                {
                    parents.Add(parentIndex, newParents[i_2]);
                }
                // recursive call, to load needed pageRef.
                // NOTE optimization? add to loadPage startParentIndex.
                LoadPage(pageNum);
            }
            else
            {
                int from = parent.GetFrom();
                // Possible exception in case kids.getSize() < parent.getCount().
                // In any case parent.getCount() has higher priority.
                // NOTE optimization? when we already found needed index
                for (int i_1 = 0; i_1 < parent.GetCount(); i_1++)
                {
                    pageRefs[from + i_1] = kids.GetAsDictionary(i_1);
                }
            }
        }
コード例 #4
0
        private void LoadPage(int pageNum)
        {
            PdfIndirectReference targetPage = pageRefs[pageNum];

            if (targetPage != null)
            {
                return;
            }
            //if we go here, we have to split PdfPages that contains pageNum
            int      parentIndex = FindPageParent(pageNum);
            PdfPages parent      = parents[parentIndex];
            PdfArray kids        = parent.GetKids();

            if (kids == null)
            {
                throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1);
            }
            int kidsCount = parent.GetCount();
            // we should handle separated pages, it means every PdfArray kids must contain either PdfPage or PdfPages,
            // mix of PdfPage and PdfPages not allowed.
            bool findPdfPages = false;

            // NOTE optimization? when we already found needed index
            for (int i = 0; i < kids.Size(); i++)
            {
                PdfDictionary page = kids.GetAsDictionary(i);
                // null values not allowed in pages tree.
                if (page == null)
                {
                    throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1);
                }
                PdfObject pageKids = page.Get(PdfName.Kids);
                if (pageKids != null)
                {
                    if (pageKids.IsArray())
                    {
                        findPdfPages = true;
                    }
                    else
                    {
                        // kids must be of type array
                        throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1);
                    }
                }
                if (document.GetReader().IsMemorySavingMode() && !findPdfPages && parent.GetFrom() + i != pageNum)
                {
                    page.Release();
                }
            }
            if (findPdfPages)
            {
                // handle mix of PdfPage and PdfPages.
                // handle count property!
                IList <PdfPages> newParents   = new List <PdfPages>(kids.Size());
                PdfPages         lastPdfPages = null;
                for (int i = 0; i < kids.Size() && kidsCount > 0; i++)
                {
                    /*
                     * We don't release pdfPagesObject in the end of each loop because we enter this for-cycle only when parent has PdfPages kids.
                     * If all of the kids are PdfPages, then there's nothing to release, because we don't release PdfPages at this point.
                     * If there are kids that are instances of PdfPage, then there's no sense in releasing them:
                     * in this case ParentTreeStructure is being rebuilt by inserting an intermediate PdfPages between the parent and a PdfPage,
                     * thus modifying the page object by resetting its parent, thus making it impossible to release the object.
                     */
                    PdfDictionary pdfPagesObject = kids.GetAsDictionary(i);
                    if (pdfPagesObject.GetAsArray(PdfName.Kids) == null)
                    {
                        // pdfPagesObject is PdfPage
                        // possible if only first kid is PdfPage
                        if (lastPdfPages == null)
                        {
                            lastPdfPages = new PdfPages(parent.GetFrom(), document, parent);
                            kids.Set(i, lastPdfPages.GetPdfObject());
                            newParents.Add(lastPdfPages);
                        }
                        else
                        {
                            // Only remove from kids if we did not replace the entry with new PdfPages
                            kids.Remove(i);
                            i--;
                        }
                        // decrement count first so that page is not counted twice when moved to lastPdfPages
                        parent.DecrementCount();
                        lastPdfPages.AddPage(pdfPagesObject);
                        kidsCount--;
                    }
                    else
                    {
                        // pdfPagesObject is PdfPages
                        int from = lastPdfPages == null?parent.GetFrom() : lastPdfPages.GetFrom() + lastPdfPages.GetCount();

                        lastPdfPages = new PdfPages(from, kidsCount, pdfPagesObject, parent);
                        newParents.Add(lastPdfPages);
                        kidsCount -= lastPdfPages.GetCount();
                    }
                }
                parents.JRemoveAt(parentIndex);
                for (int i = newParents.Count - 1; i >= 0; i--)
                {
                    parents.Add(parentIndex, newParents[i]);
                }
                // recursive call, to load needed pageRef.
                // NOTE optimization? add to loadPage startParentIndex.
                LoadPage(pageNum);
            }
            else
            {
                int from = parent.GetFrom();
                // Possible exception in case kids.getSize() < parent.getCount().
                // In any case parent.getCount() has higher priority.
                // NOTE optimization? when we already found needed index
                for (int i = 0; i < parent.GetCount(); i++)
                {
                    PdfObject kid = kids.Get(i, false);
                    if (kid is PdfIndirectReference)
                    {
                        pageRefs[from + i] = (PdfIndirectReference)kid;
                    }
                    else
                    {
                        pageRefs[from + i] = kid.GetIndirectReference();
                    }
                }
            }
        }