Beispiel #1
0
 /// <summary>
 /// Initializes a new instance from an existing dictionary. Used for object type transformation.
 /// </summary>
 /// <param name="array">The array.</param>
 protected PDFArray(PDFArray array)
     : base(array)
 {
     if (array._elements != null)
     {
         array._elements.ChangeOwner(this);
     }
 }
Beispiel #2
0
            /// <summary>
            /// Moves this instance to another array during object type transformation.
            /// </summary>
            internal void ChangeOwner(PDFArray array)
            {
                if (_ownerArray != null)
                {
                    // ???
                }

                // Set new owner.
                _ownerArray = array;

                // Set owners elements to this.
                array._elements = this;
            }
Beispiel #3
0
        /// <summary>
        /// Recursively converts the page tree into a flat array.
        /// </summary>
        PDFDictionary[] GetKids(PDFReference iref, PDFPage.InheritedValues values, PDFDictionary parent)
        {
            // TODO: inherit inheritable keys...
            PDFDictionary kid = (PDFDictionary)iref.Value;

#if true
            string type = kid.Elements.GetName(Keys.Type);
            if (type == "/Page")
            {
                PDFPage.InheritValues(kid, values);
                return(new PDFDictionary[] { kid });
            }

            if (String.IsNullOrEmpty(type))
            {
                // Type is required. If type is missing, assume it is "/Page" and hope it will work.
                // TODO Implement a "Strict" mode in PDFSharp and don't do this in "Strict" mode.
                PDFPage.InheritValues(kid, values);
                return(new PDFDictionary[] { kid });
            }
#else
            if (kid.Elements.GetName(Keys.Type) == "/Page")
            {
                PDFPage.InheritValues(kid, values);
                return(new PDFDictionary[] { kid });
            }
#endif

            Debug.Assert(kid.Elements.GetName(Keys.Type) == "/Pages");
            PDFPage.InheritValues(kid, ref values);
            List <PDFDictionary> list = new List <PDFDictionary>();
            PDFArray             kids = kid.Elements["/Kids"] as PDFArray;

            if (kids == null)
            {
                if (kid.Elements["/Kids"] is PDFReference xref3)
                {
                    kids = xref3.Value as PDFArray;
                }
            }

            foreach (PDFReference xref2 in kids)
            {
                list.AddRange(GetKids(xref2, values, kid));
            }
            int count = list.Count;
            Debug.Assert(count == kid.Elements.GetInteger("/Count"));
            return(list.ToArray());
        }
Beispiel #4
0
        /// <summary>
        /// Implements the copy mechanism.
        /// </summary>
        protected override object Copy()
        {
            PDFArray array = (PDFArray)base.Copy();

            if (array._elements != null)
            {
                array._elements = array._elements.Clone();
                int count = array._elements.Count;
                for (int idx = 0; idx < count; idx++)
                {
                    PDFItem item = array._elements[idx];
                    if (item is PDFObject)
                    {
                        array._elements[idx] = item.Clone();
                    }
                }
            }
            return(array);
        }
Beispiel #5
0
        /// <summary>
        /// Replaces the page tree by a flat array of indirect references to the pages objects.
        /// </summary>
        internal void FlattenPageTree()
        {
            // Acrobat creates a balanced tree if the number of pages is roughly more than ten. This is
            // not difficult but obviously also not necessary. I created a document with 50000 pages with
            // PDF4NET and Acrobat opened it in less than 2 seconds.

            //PDFReference xrefRoot = Document.Catalog.Elements[PDFCatalog.Keys.Pages] as PDFReference;
            //PDFDictionary[] pages = GetKids(xrefRoot, null);

            // Promote inheritable values down the page tree
            PDFPage.InheritedValues values = new PDFPage.InheritedValues();
            PDFPage.InheritValues(this, ref values);
            PDFDictionary[] pages = GetKids(Reference, values, null);

            // Replace /Pages in catalog by this object
            // xrefRoot.Value = this;

            PDFArray array = new PDFArray(Owner);

            foreach (PDFDictionary page in pages)
            {
                // Fix the parent
                page.Elements[PDFPage.Keys.Parent] = Reference;
                array.Elements.Add(page.Reference);
            }

            Elements.SetName(Keys.Type, "/Pages");
#if true
            // Direct array.
            Elements.SetValue(Keys.Kids, array);
#else
            // Indirect array.
            Document.xrefTable.Add(array);
            Elements.SetValue(Keys.Kids, array.XRef);
#endif
            Elements.SetInteger(Keys.Count, array.Elements.Count);
        }
Beispiel #6
0
        /// <summary>
        /// Inserts  pages of the specified document into this document.
        /// </summary>
        /// <param name="index">The index in this document where to insert the page .</param>
        /// <param name="document">The document to be inserted.</param>
        /// <param name="startIndex">The index of the first page to be inserted.</param>
        /// <param name="pageCount">The number of pages to be inserted.</param>
        public void InsertRange(int index, PDFDocument document, int startIndex, int pageCount)
        {
            if (document == null)
            {
                throw new ArgumentNullException("document");
            }

            if (index < 0 || index > Count)
            {
                throw new ArgumentOutOfRangeException("index", "Argument 'index' out of range.");
            }

            int importDocumentPageCount = document.PageCount;

            if (startIndex < 0 || startIndex + pageCount > importDocumentPageCount)
            {
                throw new ArgumentOutOfRangeException("startIndex", "Argument 'startIndex' out of range.");
            }

            if (pageCount > importDocumentPageCount)
            {
                throw new ArgumentOutOfRangeException("pageCount", "Argument 'pageCount' out of range.");
            }

            PDFPage[] insertPages = new PDFPage[pageCount];
            PDFPage[] importPages = new PDFPage[pageCount];

            // 1st create all new pages.
            for (int idx = 0, insertIndex = index, importIndex = startIndex;
                 importIndex < startIndex + pageCount;
                 idx++, insertIndex++, importIndex++)
            {
                PDFPage importPage = document.Pages[importIndex];
                PDFPage page       = ImportExternalPage(importPage);
                insertPages[idx] = page;
                importPages[idx] = importPage;

                Owner.IrefTable.Add(page);

                // Add page substitute to importedObjectTable.
                PDFImportedObjectTable importedObjectTable = Owner.ExternalDocumentTable.GetImportedObjectTable(importPage);
                importedObjectTable.Add(importPage.ObjectID, page.Reference);

                PagesArray.Elements.Insert(insertIndex, page.Reference);

                if (Owner.Settings.TrimMargins.AreSet)
                {
                    page.TrimMargins = Owner.Settings.TrimMargins;
                }
            }
            Elements.SetInteger(Keys.Count, PagesArray.Elements.Count);

            // 2nd copy link annotations that are in the range of the imported pages.
            for (int idx = 0, importIndex = startIndex;
                 importIndex < startIndex + pageCount;
                 idx++, importIndex++)
            {
                PDFPage importPage = document.Pages[importIndex];
                PDFPage page       = insertPages[idx];

                // Get annotations.
                PDFArray annots = importPage.Elements.GetArray(PDFPage.Keys.Annots);
                if (annots != null)
                {
                    PDFAnnotations annotations = new PDFAnnotations(Owner);

                    // Loop through annotations.
                    int count = annots.Elements.Count;
                    for (int idxAnnotation = 0; idxAnnotation < count; idxAnnotation++)
                    {
                        PDFDictionary annot = annots.Elements.GetDictionary(idxAnnotation);
                        if (annot != null)
                        {
                            string subtype = annot.Elements.GetString(PDFAnnotation.Keys.Subtype);
                            if (subtype == "/Link")
                            {
                                bool addAnnotation = false;
                                PDFLinkAnnotation newAnnotation = new PDFLinkAnnotation(Owner);

                                PDFName[] importAnnotationKeyNames = annot.Elements.KeyNames;
                                foreach (PDFName pdfItem in importAnnotationKeyNames)
                                {
                                    PDFItem impItem;
                                    switch (pdfItem.Value)
                                    {
                                    case "/BS":
                                        newAnnotation.Elements.Add("/BS", new PDFLiteral("<</W 0>>"));
                                        break;

                                    case "/F":      // /F 4
                                        impItem = annot.Elements.GetValue("/F");
                                        Debug.Assert(impItem is PDFInteger);
                                        newAnnotation.Elements.Add("/F", impItem.Clone());
                                        break;

                                    case "/Rect":      // /Rect [68.6 681.08 145.71 702.53]
                                        impItem = annot.Elements.GetValue("/Rect");
                                        Debug.Assert(impItem is PDFArray);
                                        newAnnotation.Elements.Add("/Rect", impItem.Clone());
                                        break;

                                    case "/StructParent":      // /StructParent 3
                                        impItem = annot.Elements.GetValue("/StructParent");
                                        Debug.Assert(impItem is PDFInteger);
                                        newAnnotation.Elements.Add("/StructParent", impItem.Clone());
                                        break;

                                    case "/Subtype":      // Already set.
                                        break;

                                    case "/Dest":      // /Dest [30 0 R /XYZ 68 771 0]
                                        impItem = annot.Elements.GetValue("/Dest");
                                        impItem = impItem.Clone();

                                        // Is value an array with 5 elements where the first one is an iref?
                                        PDFArray destArray = impItem as PDFArray;
                                        if (destArray != null && destArray.Elements.Count == 5)
                                        {
                                            if (destArray.Elements[0] is PDFReference iref)
                                            {
                                                iref = RemapReference(insertPages, importPages, iref);
                                                if (iref != null)
                                                {
                                                    destArray.Elements[0] = iref;
                                                    newAnnotation.Elements.Add("/Dest", destArray);
                                                    addAnnotation = true;
                                                }
                                            }
                                        }
                                        break;

                                    default:
#if DEBUG_
                                        Debug - Break.Break(true);
#endif
                                        break;
                                    }
                                }
                                // Add newAnnotations only it points to an imported page.
                                if (addAnnotation)
                                {
                                    annotations.Add(newAnnotation);
                                }
                            }
                        }
                    }

                    // At least one link annotation found?
                    if (annotations.Count > 0)
                    {
                        //Owner._irefTable.Add(annotations);
                        page.Elements.Add(PDFPage.Keys.Annots, annotations);
                    }
                }
            }
        }
Beispiel #7
0
 internal ArrayElements(PDFArray array)
 {
     _elements   = new List <PDFItem>();
     _ownerArray = array;
 }