/// <summary>
 /// Sets the color to the specified key.
 /// </summary>
 /// <param name="elements">The elements.</param>
 /// <param name="key">The key.</param>
 /// <param name="color">The color.</param>
 public static void SetColor(this PdfDictionary.DictionaryElements elements, string key, XColor color)
 {
     if (elements == null) { throw new ArgumentNullException("elements"); }
     if (!string.IsNullOrEmpty(key))
     {
         var arr = new PdfArray();
         arr.Elements.Add(new PdfReal(color.R / (double)byte.MaxValue));
         arr.Elements.Add(new PdfReal(color.G / (double)byte.MaxValue));
         arr.Elements.Add(new PdfReal(color.B / (double)byte.MaxValue));
         elements[key] = arr;
     }
 }
Exemplo n.º 2
0
 internal PdfContents(PdfArray array)
   : base(array)
 {
   int count = Elements.Count;
   for (int idx = 0; idx < count; idx++)
   {
     // Convert the references from PdfDictionary to PdfContent
     PdfItem item = Elements[idx];
     PdfReference iref = item as PdfReference;
     if (iref != null && iref.Value is PdfDictionary)
     {
       // The following line is correct!
       new PdfContent((PdfDictionary)iref.Value);
     }
     else
       throw new InvalidOperationException("Unexpected item in a content stream array.");
   }
 }
Exemplo n.º 3
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 rougly 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 = this.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
      // incdirect array
      this.Document.xrefTable.Add(array);
      Elements.SetValue(Keys.Kids, array.XRef);
#endif
      Elements.SetInteger(Keys.Count, array.Elements.Count);
    }
Exemplo n.º 4
0
        private static Dictionary <string, string> GetFieldsFromPDF(PdfDocument FormDocument)
        {
            Dictionary <string, string> dictPDFFields = new Dictionary <string, string>();

            if (FormDocument == null || FormDocument.AcroForm == null)
            {
                throw new Exception("No PDF with fillable form submitted");
            }


            PdfAcroForm af = FormDocument.AcroForm;

            foreach (string key in af.Fields.Names)
            {
                try {
                    var field = af.Fields[key];
                    if (field is PdfTextField)
                    {
                        dictPDFFields.Add(key, ((PdfTextField)field).Text);
                    }
                    else if (field is PdfCheckBoxField)
                    {
                        dictPDFFields.Add(key, ((PdfCheckBoxField)field).Checked.ToString());
                    }
                    else if (field is PdfSignatureField)
                    {
                        dictPDFFields.Add(key, ""); //Leave empty since we just do image filling
                    }
                    else if (field is PdfComboBoxField)
                    {
                        if (((PdfComboBoxField)field).Value is PdfString)
                        {
                            dictPDFFields.Add(key, (((PdfComboBoxField)field).Value as PdfString).Value);
                        }
                        else
                        {
                            dictPDFFields.Add(key, ((PdfComboBoxField)field).Value?.ToString());
                        }
                    }
                    else if (field is PdfRadioButtonField)
                    {
                        dictPDFFields.Add(key, ((PdfRadioButtonField)field).Value?.ToString());
                    }
                    else if (field is PdfListBoxField)
                    {
                        PdfListBoxField pl     = (PdfListBoxField)field;
                        string          values = "";
                        if (pl.Value is PdfArray)
                        {
                            PdfSharp.Pdf.PdfArray pa = (PdfSharp.Pdf.PdfArray)pl.Value;

                            foreach (PdfString pi in pa.Elements.Items)
                            {
                                if (values.Length > 0)
                                {
                                    values += ",";
                                }
                                values += pi.Value;
                            }
                        }
                        else
                        {
                            values = pl.Value.ToString();
                        }
                        dictPDFFields.Add(key, values);
                    }
                    else
                    {
                        dictPDFFields.Add(key, "Unsupported Type");
                    }
                } catch (Exception e) {
                    throw new Exception("Scan of Field '" + key + " failed.  " + e.Message);
                }
            }

            return(dictPDFFields);
        }
 /// <summary>
 /// Encrypts an array.
 /// </summary>
 void EncryptArray(PdfArray array)
 {
   int count = array.Elements.Count;
   for (int idx = 0; idx < count; idx++)
   {
     PdfItem item = array.Elements[idx];
     PdfString value1;
     PdfDictionary value2;
     PdfArray value3;
     if ((value1 = item as PdfString) != null)
       EncryptString(value1);
     else if ((value2 = item as PdfDictionary) != null)
       EncryptDictionary(value2);
     else if ((value3 = item as PdfArray) != null)
       EncryptArray(value3);
   }
 }
Exemplo n.º 6
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.SetOwner(this);
 }
Exemplo n.º 7
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)
        {
            // @PDF/UA
            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.FormTable.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)
                                        {
                                            PdfReference iref = destArray.Elements[0] as PdfReference;
                                            if (iref != null)
                                            {
                                                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[PdfPage.Keys.Annots] = annotations;
                    }
                }
            }

            // @PDF/UA: Pages were imported.
            if (_document._uaManager != null)
            {
                _document.Events.OnPageAdded(_document, new PageEventArgs {
                    EventType = PageEventType.Imported
                });
            }
        }
Exemplo n.º 8
0
 PdfArray CreateArray(Type type, PdfArray oldArray)
 {
   ConstructorInfo ctorInfo;
   PdfArray array;
   if (oldArray == null)
   {
     // Use contstructor with signature 'Ctor(PdfDocument owner)'.
     ctorInfo = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
       null, new Type[] { typeof(PdfDocument) }, null);
     Debug.Assert(ctorInfo != null, "No appropriate constructor found for type: " + type.Name);
     array = ctorInfo.Invoke(new object[] { this.owner.Owner }) as PdfArray;
   }
   else
   {
     // Use contstructor with signature 'Ctor(PdfDictionary dict)'.
     ctorInfo = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
       null, new Type[] { typeof(PdfArray) }, null);
     Debug.Assert(ctorInfo != null, "No appropriate constructor found for type: " + type.Name);
     array = ctorInfo.Invoke(new object[] { oldArray }) as PdfArray;
   }
   return array;
 }
Exemplo n.º 9
0
    public PdfArray ReadArray(PdfArray array, bool includeReferences)
    {
      Debug.Assert(Symbol == Symbol.BeginArray);

      if (array == null)
        array = new PdfArray(this.document);

      int sp = this.stack.SP;
      ParseObject(Symbol.EndArray);
      int count = this.stack.SP - sp;
      PdfItem[] items = this.stack.ToArray(sp, count);
      this.stack.Reduce(count);
      for (int idx = 0; idx < count; idx++)
      {
        PdfItem val = items[idx];
        if (includeReferences && val is PdfReference)
          val = ReadReference((PdfReference)val, includeReferences);
        array.Elements.Add(val);
      }
      return array;
    }
Exemplo n.º 10
0
        // Write labels to the PDF
        internal void WriteLabels ()
        {
            if (!edited) {
                return;
            }

            // Grab the labels element, creating it if necessary
            PdfDictionary labels_dict;
            if (!pdf_elements.ContainsKey (name_labels)) {
                labels_dict = new PdfDictionary (pdf_document);
                pdf_elements.Add (name_labels, labels_dict);
            } else {
                labels_dict = pdf_elements.GetDictionary (name_labels);
            }
            labels_dict.Elements.Clear ();

            // Create the number tree
            PdfArray number_tree = new PdfArray (pdf_document);

            // Add the range-start, attrib-dict pairs
            foreach (int range_start in page_labels.Keys)
            {
                number_tree.Elements.Add (new PdfInteger (range_start));
                PageLabelFormat label_format = page_labels[range_start];
                PdfDictionary r_attribs = new PdfDictionary (pdf_document);

                if (label_format.number_style.Length > 0) {
                    r_attribs.Elements.Add (name_fmt, new PdfName (label_format.number_style));
                }
                if (label_format.first_number > 1) {
                    r_attribs.Elements.Add (name_start_at, new PdfInteger (label_format.first_number));
                }
                if (label_format.prefix.Length > 0) {
                    r_attribs.Elements.Add (name_prefix, new PdfString (label_format.prefix));
                }
                number_tree.Elements.Add (r_attribs);
            }
            labels_dict.Elements.Add (name_numtree, number_tree);
        }
Exemplo n.º 11
0
    static void Main(string[] args)
    {
      // Get a fresh copy of the sample PDF file
      string filename = "Portable Document Format.pdf";
      File.Copy(Path.Combine("../../../../../PDFs/", filename), 
        Path.Combine(Directory.GetCurrentDirectory(), filename), true);

      // Read document into memory for modification
      PdfDocument document = PdfReader.Open(filename);

      // The current version of PDFsharp doesn't support the concept of
      // 'actions'. Actions will come in a future version, but if you need them
      // now, you can have them 'handmade'.
      //
      // This sample works on PDF objects directly, therefore some knowledge of
      // the structure of PDF is required.
      // If you are not familiar with the portable document format, first read
      // at least chapter 3 in Adobe's PDF Reference 
      // (http://partners.adobe.com/public/developer/pdf/index_reference.html).
      // If you can read German, I recommend chapter 12 of 'Die PostScript & 
      // PDF-Bibel', a much more interesting reading than the bone-dry Adobe
      // books (http://www.pdflib.com/de/produkte/mehr/bibel/index.html).
      //
      // The sample task is to add an 'open action' to the document so that it
      // starts with the content of page 3 magnified just enough to fit the
      // height of the page within the window.

      // First we have to create a new dictionary that defines the action.
      PdfDictionary dict = new PdfDictionary(document);

      // According to the PDF Reference the dictionary requires two elements.
      // A key /S that specifies the 'GoTo' action,
      // and a key /D that describes the destination.

      // Adding a name as value of key /S is easy.
      dict.Elements["/S"] = new PdfName("/GoTo");

      // The destination is described by an array.
      PdfArray array = new PdfArray(document);

      // Set the array as the value of key /D.
      // This makes the array a direct object of the dictionary.
      dict.Elements["/D"] = array;

      // Now add the elements to the array. According to the PDF Reference it
      // must be three for a page as the target of a 'GoTo' action.
      // The first element is an indirect reference to the destination page.
      // To add an indirect reference to the page three, we first need the 
      // PdfReference object of that page.
      // (The index in the Pages collection is zero based, therefore Pages[2])
      PdfReference iref = PdfInternals.GetReference(document.Pages[2]);

      // Add the reference to the third page as the first array element.
      // Adding the iref (instead of the PdfPage object itself) makes it an 
      // indirect reference.
      array.Elements.Add(iref);

      // The second element is the name /FitV to indicate 'fit vertically'. 
      array.Elements.Add(new PdfName("/FitV"));

      // /FitV requires the horizontal coordinate that will be positioned at the
      // left edge of the window. We set -32768 because Acrobat uses this value
      // to show the full page (it means 'left aligned' anyway if the window is
      // so small that a horizontal scroll bar is required).
      array.Elements.Add(new PdfInteger(-32768));

      // Now that the action dictionary is complete, we can add it to the
      // document's object table.
      // Adding an object to the object table makes it an indirect object.
      document.Internals.AddObject(dict);

      // Finally we must add the action dictionary to the /OpenAction key of
      // the document's catalog as an indirect value.
      document.Internals.Catalog.Elements["/OpenAction"] = 
        PdfInternals.GetReference(dict);

      // Using PDFsharp we never deal with object numbers. We simply put the
      // objects together and the PDFsharp framework does the rest.

      // Save the document...
      document.Save(filename);
      // ...and start a viewer.
      Process.Start(filename);
    }
    PdfDictionary BuildShadingFunction3(GradientStopCollection gradients, bool softMask, PdfColorMode colorMode)
    {
      int count = gradients.Count;
      Debug.Assert(count >= 2);

      //        // Build a Type 3 function with an array of n-1 Type 2 functions

      PdfDictionary fn1 = new PdfDictionary();


      fn1.Elements["/FunctionType"] = new PdfInteger(3);  // Type 3 - Stitching Function
      fn1.Elements["/Domain"] = new PdfLiteral("[0 1]");
      fn1.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]");
      PdfArray fnarray = new PdfArray();
      fn1.Elements["/Functions"] = fnarray;

      StringBuilder bounds = new StringBuilder("[");
      StringBuilder encode = new StringBuilder("[");

      for (int idx = 1; idx < count; idx++)
      {
        PdfDictionary fn2 = new PdfDictionary();
        fn2.Elements["/FunctionType"] = new PdfInteger(2);
        Color clr0 = gradients[idx - 1].Color;
        Color clr1 = gradients[idx].Color;
        if (softMask)
        {
          fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0.ScA) + "]");
          fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1.ScA) + "]");
          fn2.Elements["/Range"] = new PdfLiteral("[0 1]");
        }
        else
        {
          fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0, colorMode) + "]");
          fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1, colorMode) + "]");
          fn2.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]");
        }
        fn2.Elements["/Domain"] = new PdfLiteral("[0 1]");
        fn2.Elements["/N"] = new PdfInteger(1);
        fnarray.Elements.Add(fn2);
        if (idx > 1)
        {
          bounds.Append(' ');
          encode.Append(' ');
        }
        if (idx < count - 1)
          bounds.Append(PdfEncoders.ToString(gradients[idx].Offset));
        encode.Append("0 1");
      }
      bounds.Append(']');
      encode.Append(']');
      fn1.Elements["/Bounds"] = new PdfLiteral(bounds.ToString());
      fn1.Elements["/Encode"] = new PdfLiteral(encode.ToString());

      return fn1;
    }
    /// <summary>
    /// Builds the shading function of the specified gradient stop collection.
    /// </summary>
    protected PdfDictionary BuildShadingFunction(GradientStopCollection gradients, bool softMask, PdfColorMode colorMode, bool reverse, out PdfDictionary funcReverse)
    {
      PdfDictionary func = new PdfDictionary();
      int count = gradients.Count;
      Debug.Assert(count >= 2);

      if (CanOptimizeForTwoColors(gradients))
      {
        funcReverse = null;

        // Build a Type 3 function with an array of 2 Type 2 functions
        func.Elements["/FunctionType"] = new PdfInteger(3);  // Type 3 - Stitching Function
        func.Elements["/Domain"] = new PdfLiteral("[0 1]");
        PdfArray fnarray = new PdfArray();
        func.Elements["/Functions"] = fnarray;

        StringBuilder bounds = new StringBuilder("[");
        StringBuilder encode = new StringBuilder("[");

        for (int idx = 1; idx < count; idx++)
        {
          PdfDictionary fn2 = new PdfDictionary();
          fn2.Elements["/FunctionType"] = new PdfInteger(2);
          Color clr0 = gradients[idx - 1].Color;
          Color clr1 = gradients[idx].Color;
          if (softMask)
          {
            fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0.ScA) + "]");
            fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1.ScA) + "]");
            fn2.Elements["/Range"] = new PdfLiteral("[0 1]");
          }
          else
          {
            fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0, colorMode) + "]");
            fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1, colorMode) + "]");
            fn2.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]");
          }
          fn2.Elements["/Domain"] = new PdfLiteral("[0 1]");
          fn2.Elements["/N"] = new PdfInteger(1);
          fnarray.Elements.Add(fn2);
          if (idx > 1)
          {
            bounds.Append(' ');
            encode.Append(' ');
          }
          if (idx < count - 1)
            bounds.Append(PdfEncoders.ToString(gradients[idx].Offset));
          encode.Append(reverse ? "1 0" : "0 1");
        }
        bounds.Append(']');
        encode.Append(']');
        func.Elements["/Bounds"] = new PdfLiteral(bounds.ToString());
        func.Elements["/Encode"] = new PdfLiteral(encode.ToString());
      }
      else
      {
#if true
        funcReverse = BuildShadingFunction3(gradients, softMask, colorMode);
        Context.PdfDocument.Internals.AddObject(funcReverse);

        func.Elements["/FunctionType"] = new PdfInteger(3);  // Type 3 - Stitching Function
        func.Elements["/Domain"] = new PdfLiteral("[0 1]");
        func.Elements["/Encode"] = new PdfLiteral("[1 0]");
        func.Elements["/Bounds"] = new PdfLiteral("[]");
        func.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]");
        PdfArray fnarray0 = new PdfArray();
        fnarray0.Elements.Add(funcReverse);
        func.Elements["/Functions"] = fnarray0;

#else
        //        // Build a Type 3 function with an array of n-1 Type 2 functions

        PdfDictionary fn1 = new PdfDictionary();


        func.Elements["/FunctionType"] = new PdfInteger(3);  // Type 3 - Stitching Function
        func.Elements["/Domain"] = new PdfLiteral("[0 1]");
        func.Elements["/Encode"] = new PdfLiteral("[1 0]");
        func.Elements["/Bounds"] = new PdfLiteral("[]");
        func.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]");
        PdfArray fnarray0 = new PdfArray();
        fnarray0.Elements.Add(fn1);
        func.Elements["/Functions"] = fnarray0;





        fn1.Elements["/FunctionType"] = new PdfInteger(3);  // Type 3 - Stitching Function
        fn1.Elements["/Domain"] = new PdfLiteral("[0 1]");
        fn1.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]");
        PdfArray fnarray = new PdfArray();
        fn1.Elements["/Functions"] = fnarray;

        StringBuilder bounds = new StringBuilder("[");
        StringBuilder encode = new StringBuilder("[");

        for (int idx = 1; idx < count; idx++)
        {
          PdfDictionary fn2 = new PdfDictionary();
          fn2.Elements["/FunctionType"] = new PdfInteger(2);
          Color clr0 = gradients[idx - 1].Color;
          Color clr1 = gradients[idx].Color;
          if (softMask)
          {
            fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0.ScA) + "]");
            fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1.ScA) + "]");
            fn2.Elements["/Range"] = new PdfLiteral("[0 1]");
          }
          else
          {
            fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0, colorMode) + "]");
            fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1, colorMode) + "]");
            fn2.Elements["/Range"] = new PdfLiteral("[0 1 0 1 0 1]");
          }
          fn2.Elements["/Domain"] = new PdfLiteral("[0 1]");
          fn2.Elements["/N"] = new PdfInteger(1);
          //this.renderer.Owner.Internals.AddObject(fn2);
          //fnarray.Elements.Add(fn2.Reference);
          fnarray.Elements.Add(fn2);
          if (idx > 1)
          {
            bounds.Append(' ');
            encode.Append(' ');
          }
          if (idx < count - 1)
            bounds.Append(PdfEncoders.ToString(gradients[idx].Offset));
          encode.Append("0 1");
        }
        bounds.Append(']');
        encode.Append(']');
        fn1.Elements["/Bounds"] = new PdfLiteral(bounds.ToString());
        fn1.Elements["/Encode"] = new PdfLiteral(encode.ToString());
#endif
      }
      return func;
    }
Exemplo n.º 14
0
        void SplitDestinationPage(PdfArray destination)  // Reference: 8.2 Destination syntax / Page 582
        {
            // ReSharper disable HeuristicUnreachableCode
//#pragma warning disable 162

            // The destination page may not yet have been transformed to PdfPage.
            PdfDictionary destPage = (PdfDictionary)((PdfReference)destination.Elements[0]).Value;
            PdfPage       page     = destPage as PdfPage;

            if (page == null)
            {
                page = new PdfPage(destPage);
            }

            DestinationPage = page;
            PdfName type = destination.Elements[1] as PdfName;

            if (type != null)
            {
                PageDestinationType = (PdfPageDestinationType)Enum.Parse(typeof(PdfPageDestinationType), type.Value.Substring(1), true);
                switch (PageDestinationType)
                {
                // [page /XYZ left top zoom] -- left, top, and zoom can be null.
                case PdfPageDestinationType.Xyz:
                    Left = destination.Elements.GetNullableReal(2);
                    Top  = destination.Elements.GetNullableReal(3);
                    Zoom = destination.Elements.GetNullableReal(4);     // For this parameter, null and 0 have the same meaning.
                    break;

                // [page /Fit]
                case PdfPageDestinationType.Fit:
                    // /Fit has no parameters.
                    break;

                // [page /FitH top] -- top can be null.
                case PdfPageDestinationType.FitH:
                    Top = destination.Elements.GetNullableReal(2);
                    break;

                // [page /FitV left] -- left can be null.
                case PdfPageDestinationType.FitV:
                    Left = destination.Elements.GetNullableReal(2);
                    break;

                // [page /FitR left bottom right top] -- left, bottom, right, and top must not be null.
                // TODO An exception in GetReal leads to an inconsistent document. Deal with that - e.g. by registering the corruption and preventing the user from saving the corrupted document.
                case PdfPageDestinationType.FitR:
                    Left   = destination.Elements.GetReal(2);
                    Bottom = destination.Elements.GetReal(3);
                    Right  = destination.Elements.GetReal(4);
                    Top    = destination.Elements.GetReal(5);
                    break;

                // [page /FitB]
                case PdfPageDestinationType.FitB:
                    // /Fit has no parameters.
                    break;

                // [page /FitBH top] -- top can be null.
                case PdfPageDestinationType.FitBH:
                    Top = destination.Elements.GetReal(2);
                    break;

                // [page /FitBV left] -- left can be null.
                case PdfPageDestinationType.FitBV:
                    Left = destination.Elements.GetReal(2);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

//#pragma warning restore 162
            // ReSharper restore HeuristicUnreachableCode
        }
Exemplo n.º 15
0
        /// <summary>
        /// Initializes this instance from an existing PDF document.
        /// </summary>
        void Initialize()
        {
            string title;

            if (Elements.TryGetString(Keys.Title, out title))
            {
                Title = title;
            }

            PdfReference parentRef = Elements.GetReference(Keys.Parent);

            if (parentRef != null)
            {
                PdfOutline parent = parentRef.Value as PdfOutline;
                if (parent != null)
                {
                    Parent = parent;
                }
            }

            Count = Elements.GetInteger(Keys.Count);

            PdfArray colors = Elements.GetArray(Keys.C);

            if (colors != null && colors.Elements.Count == 3)
            {
                double r = colors.Elements.GetReal(0);
                double g = colors.Elements.GetReal(1);
                double b = colors.Elements.GetReal(2);
                TextColor = XColor.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255));
            }

            // Style directly works on dictionary element.

            PdfItem dest = Elements.GetValue(Keys.Dest);
            PdfItem a    = Elements.GetValue(Keys.A);

            Debug.Assert(dest == null || a == null, "Either destination or goto action.");

            PdfArray destArray = null;

            if (dest != null)
            {
                destArray = dest as PdfArray;
                if (destArray != null)
                {
                    SplitDestinationPage(destArray);
                }
                else
                {
                    Debug.Assert(false, "See what to do when this happened.");
                }
            }
            else if (a != null)
            {
                // The dictionary should be a GoTo action.
                PdfDictionary action = a as PdfDictionary;
                if (action != null && action.Elements.GetName(PdfAction.Keys.S) == "/GoTo")
                {
                    dest      = action.Elements[PdfGoToAction.Keys.D];
                    destArray = dest as PdfArray;
                    if (destArray != null)
                    {
                        // Replace Action with /Dest entry.
                        Elements.Remove(Keys.A);
                        Elements.Add(Keys.Dest, destArray);
                        SplitDestinationPage(destArray);
                    }
                    else
                    {
                        throw new Exception("Destination Array expected.");
                    }
                }
                else
                {
                    Debug.Assert(false, "See what to do when this happened.");
                }
            }
            else
            {
                // Neither destination page nor GoTo action.
            }

            InitializeChildren();
        }
Exemplo n.º 16
0
 internal ArrayElements(PdfArray array)
 {
     _elements   = new List <PdfItem>();
     _ownerArray = array;
 }
Exemplo n.º 17
0
    /// <summary>
    /// Reads PDF object from input stream.
    /// </summary>
    /// <param name="pdfObject">Either the instance of a derived type or null. If it is null
    /// an appropriate object is created.</param>
    /// <param name="objectID">The address of the object.</param>
    /// <param name="includeReferences">If true, specifies that all indirect objects
    /// are included recursively.</param>
    public PdfObject ReadObject(PdfObject pdfObject, PdfObjectID objectID, bool includeReferences)
    {
      MoveToObject(objectID);
      int objectNumber = ReadInteger();
      int generationNumber = ReadInteger();
#if DEBUG
      // The following assertion sometime failed (see below)
      //Debug.Assert(objectID == new PdfObjectID(objectNumber, generationNumber));
      if (objectID != new PdfObjectID(objectNumber, generationNumber))
      {
        // A special kind of bug? Or is this an undocumented PDF feature?
        // PDF4NET 2.6 provides a sample called 'Unicode', which produces a file 'unicode.pdf'
        // The iref table of this file contains the following entries:
        //    iref
        //    0 148
        //    0000000000 65535 f 
        //    0000000015 00000 n 
        //    0000000346 00000 n 
        //    ....
        //    0000083236 00000 n 
        //    0000083045 00000 n 
        //    0000083045 00000 n 
        //    0000083045 00000 n 
        //    0000083045 00000 n 
        //    0000080334 00000 n 
        //    ....
        // Object 84, 85, 86, and 87 maps to the same dictionary, but all PDF readers I tested
        // ignores this mismatch! The following assertion failed about 50 times with this file.
#if true_
        string message = String.Format("xref entry {0} {1} maps to object {2} {3}.",
          objectID.ObjectNumber, objectID.GenerationNumber, objectNumber, generationNumber);
        Debug.Assert(false, message);
#endif
      }
#endif
      // Always use object ID from iref table (see above)
      objectNumber = objectID.ObjectNumber;
      generationNumber = objectID.GenerationNumber;
#if true_
      Debug.WriteLine(String.Format("obj: {0} {1}", objectNumber, generationNumber));
#endif
      ReadSymbol(Symbol.Obj);

      bool checkForStream = false;
      Symbol symbol = ScanNextToken();
      switch (symbol)
      {
        case Symbol.BeginArray:
          PdfArray array;
          if (pdfObject == null)
            array = new PdfArray(this.document);
          else
            array = (PdfArray)pdfObject;
          //PdfObject.RegisterObject(array, objectID, generation);
          pdfObject = ReadArray(array, includeReferences);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          break;

        case Symbol.BeginDictionary:
          PdfDictionary dict;
          if (pdfObject == null)
            dict = new PdfDictionary(this.document);
          else
            dict = (PdfDictionary)pdfObject;
          //PdfObject.RegisterObject(dict, objectID, generation);
          checkForStream = true;
          pdfObject = ReadDictionary(dict, includeReferences);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          break;

        // Acrobat 6 Professional proudly presents: The Null object!
        // Even with a one-digit object number an indirect reference «x 0 R» to this object is
        // one character larger than the direct use of «null». Probable this is the reason why
        // it is true that Acrobat Web Capture 6.0 creates this object, but obviously never 
        // creates a reference to it!
        case Symbol.Null:
          pdfObject = new PdfNullObject(this.document);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.Boolean:
          pdfObject = new PdfBooleanObject(this.document, this.lexer.Token == Boolean.TrueString);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.Integer:
          pdfObject = new PdfIntegerObject(this.document, this.lexer.TokenToInteger);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.UInteger:
          pdfObject = new PdfUIntegerObject(this.document, this.lexer.TokenToUInteger);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.Real:
          pdfObject = new PdfRealObject(this.document, this.lexer.TokenToReal);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.String:
          pdfObject = new PdfStringObject(this.document, this.lexer.Token);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.Name:
          pdfObject = new PdfNameObject(this.document, this.lexer.Token);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.Keyword:
          // Should not come here anymore
          throw new NotImplementedException("Keyword");

        default:
          // Should not come here anymore
          throw new NotImplementedException("unknown token");
      }
      symbol = ScanNextToken();
      if (symbol == Symbol.BeginStream)
      {
        PdfDictionary dict = (PdfDictionary)pdfObject;
        Debug.Assert(checkForStream, "Unexpected stream...");
        int length = GetStreamLength(dict);
        byte[] bytes = this.lexer.ReadStream(length);
#if true_
        if (dict.Elements.GetString("/Filter") == "/FlateDecode")
        {
          if (dict.Elements["/Subtype"] == null)
          {
            try
            {
              byte[] decoded = Filtering.FlateDecode.Decode(bytes);
              if (decoded.Length == 0)
                goto End;
              string pageContent = Filtering.FlateDecode.DecodeToString(bytes);
              if (pageContent.Length > 100)
                pageContent = pageContent.Substring(pageContent.Length - 100);
              pageContent.GetType();
              bytes = decoded;
              dict.Elements.Remove("/Filter");
              dict.Elements.SetInteger("/Length", bytes.Length);
            }
            catch
            {
            }
          }
        End:;
        }
#endif
        PdfDictionary.PdfStream stream = new PdfDictionary.PdfStream(bytes, dict);
        dict.Stream = stream;
        ReadSymbol(Symbol.EndStream);
        symbol = ScanNextToken();
      }
      if (symbol != Symbol.EndObj)
        throw new PdfReaderException(PSSR.UnexpectedToken(this.lexer.Token));
      return pdfObject;
    }
    //void RealizeImageBrush(ImageBrush brush, XForm xform)
    //{
    //}

    //void RealizeVisualBrush(VisualBrush brush, XForm xform)
    //{
    //}

    /// <summary>
    /// Builds the shading function of the specified gradient stop collection.
    /// </summary>
    PdfDictionary BuildShadingFunction(GradientStopCollection gradients, PdfColorMode colorMode)
    {
      bool softMask = this.writer.renderMode == RenderMode.SoftMask;
      PdfDictionary func = new PdfDictionary();
      int count = gradients.Count;
      Debug.Assert(count >= 2);
      if (count == 2)
      {
        // Build one Type 2 function
        func.Elements["/FunctionType"] = new PdfInteger(2); // Type 2 - Exponential Interpolation Function
        Color clr0 = gradients[0].Color;
        Color clr1 = gradients[1].Color;
        if (softMask)
        {
          clr0 = Utils.AlphaToGray(clr0);
          clr1 = Utils.AlphaToGray(clr1);
        }
        func.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0, colorMode) + "]");
        func.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1, colorMode) + "]");
        func.Elements["/Domain"] = new PdfLiteral("[0 1]");
        func.Elements["/N"] = new PdfInteger(1); // be linear
      }
      else
      {
        // Build a Type 3 function with an array of n-1 Type 2 functions
        func.Elements["/FunctionType"] = new PdfInteger(3); // Type 3 - Stitching Function
        func.Elements["/Domain"] = new PdfLiteral("[0 1]");
        PdfArray fnarray = new PdfArray();
        func.Elements["/Functions"] = fnarray;

        StringBuilder bounds = new StringBuilder("[");
        StringBuilder encode = new StringBuilder("[");

        for (int idx = 1; idx < count; idx++)
        {
          PdfDictionary fn2 = new PdfDictionary();
          fn2.Elements["/FunctionType"] = new PdfInteger(2);
          Color clr0 = gradients[idx - 1].Color;
          Color clr1 = gradients[idx].Color;
          if (softMask)
          {
            clr0 = Utils.AlphaToGray(clr0);
            clr1 = Utils.AlphaToGray(clr1);
          }
          fn2.Elements["/C0"] = new PdfLiteral("[" + PdfEncoders.ToString(clr0, colorMode) + "]");
          fn2.Elements["/C1"] = new PdfLiteral("[" + PdfEncoders.ToString(clr1, colorMode) + "]");
          fn2.Elements["/Domain"] = new PdfLiteral("[0 1]");
          fn2.Elements["/N"] = new PdfInteger(1);
          //this.renderer.Owner.Internals.AddObject(fn2);
          //fnarray.Elements.Add(fn2.Reference);
          fnarray.Elements.Add(fn2);
          if (idx > 1)
          {
            bounds.Append(' ');
            encode.Append(' ');
          }
          if (idx < count - 1)
            bounds.Append(PdfEncoders.ToString(gradients[idx].Offset));
          encode.Append("0 1");
        }
        bounds.Append(']');
        //encode.Append(" 0 1");
        encode.Append(']');
        func.Elements["/Bounds"] = new PdfLiteral(bounds.ToString());
        func.Elements["/Encode"] = new PdfLiteral(encode.ToString());
      }
      return func;
    }
Exemplo n.º 19
0
    /// <summary>
    /// Parses whatever comes until the specified stop symbol is reached.
    /// </summary>
    void ParseObject(Symbol stop)
    {
#if DEBUG_
      ParseObjectCounter++;
      Debug.WriteLine(ParseObjectCounter.ToString());
      if (ParseObjectCounter == 178)
        GetType();
#endif
      Symbol symbol;
      while ((symbol = ScanNextToken()) != Symbol.Eof)
      {
        if (symbol == stop)
          return;

        switch (symbol)
        {
          case Symbol.Comment:
            // ignore comments
            break;

          case Symbol.Null:
            this.stack.Shift(PdfNull.Value);
            break;

          case Symbol.Boolean:
            this.stack.Shift(new PdfBoolean(this.lexer.TokenToBoolean));
            break;

          case Symbol.Integer:
            this.stack.Shift(new PdfInteger(this.lexer.TokenToInteger));
            break;

          case Symbol.UInteger:
            this.stack.Shift(new PdfUInteger(this.lexer.TokenToUInteger));
            break;

          case Symbol.Real:
            this.stack.Shift(new PdfReal(this.lexer.TokenToReal));
            break;

          case Symbol.String:
            //this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.PDFDocEncoding));
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.RawEncoding));
            break;

          case Symbol.UnicodeString:
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.Unicode));
            break;

          case Symbol.HexString:
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.HexLiteral));
            break;

          case Symbol.UnicodeHexString:
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.Unicode | PdfStringFlags.HexLiteral));
            break;

          case Symbol.Name:
            this.stack.Shift(new PdfName(this.lexer.Token));
            break;

          case Symbol.R:
            {
              Debug.Assert(this.stack.GetItem(-1) is PdfInteger && this.stack.GetItem(-2) is PdfInteger);
              PdfObjectID objectID = new PdfObjectID(this.stack.GetInteger(-2), this.stack.GetInteger(-1));

              PdfReference iref = this.document.irefTable[objectID];
              if (iref == null)
              {
                // If a document has more than one PdfXRefTable it is possible that the first trailer has
                // indirect references to objects whos iref entry is not yet read in.
                if (this.document.irefTable.IsUnderConstruction)
                {
                  // XRefTable not complete when trailer is read. Create temporary irefs that are
                  // removed later in PdfTrailer.FixXRefs.
                  iref = new PdfReference(objectID, 0);
                  this.stack.Reduce(iref, 2);
                  break;
                }
                // PDF Reference section 3.2.9:
                // An indirect reference to an undefined object is not an error;
                // it is simply treated as a reference to the null object.
                this.stack.Reduce(PdfNull.Value, 2);
                // Let's see what null objects are good for...
                //Debug.Assert(false, "Null object detected!");
                //this.stack.Reduce(PdfNull.Value, 2);
              }
              else
                this.stack.Reduce(iref, 2);
              break;
            }

          case Symbol.BeginArray:
            PdfArray array = new PdfArray(this.document);
            ReadArray(array, false);
            this.stack.Shift(array);
            break;

          case Symbol.BeginDictionary:
            PdfDictionary dict = new PdfDictionary(this.document);
            ReadDictionary(dict, false);
            this.stack.Shift(dict);
            break;

          case Symbol.BeginStream:
            throw new NotImplementedException();

          default:
            string error = this.lexer.Token;
            Debug.Assert(false, "Unexpected: " + error);
            break;
        }
      }
      throw new PdfReaderException("Unexpected end of file.");
    }
Exemplo n.º 20
0
 internal ArrayElements(PdfArray array)
 {
   this.elements = new ArrayList();
   this.owner = array;
 }
      /// <summary>
      /// Retrieves the raw data for the colorspace.
      /// </summary>
      /// <returns>The raw data from the PdfArray of PdfReference.</returns>
      protected virtual IEnumerable<byte> GetRawPalette(PdfArray array)
      {
        if (array == null) throw new ArgumentNullException("array", "The indexed color array was null.");

        foreach(var item in array.Elements) {
          var number = (item as PdfInteger);
          if (number == null) yield return(0);
          yield return (Convert.ToByte(number.Value));
        }
      }
Exemplo n.º 22
0
 /// <summary>
 /// Moves this instance to another dictionary during object type transformation.
 /// </summary>
 internal void SetOwner(PdfArray array)
 {
   this.owner = array;
   array.elements = this;
 }