/// <summary> /// Gets the <see cref="PDFAnnotation"/> at the specified index. /// </summary> public PDFAnnotation this[int index] { get { PDFReference iref; PDFDictionary dict; PDFItem item = Elements[index]; if ((iref = item as PDFReference) != null) { Debug.Assert(iref.Value is PDFDictionary, "Reference to dictionary expected."); dict = (PDFDictionary)iref.Value; } else { Debug.Assert(item is PDFDictionary, "Dictionary expected."); dict = (PDFDictionary)item; } if (!(dict is PDFAnnotation annotation)) { annotation = new PDFGenericAnnotation(dict); if (iref == null) { Elements[index] = annotation; } } return(annotation); } }
/// <summary> /// Gets the value from the index in the /Opt array. /// </summary> protected string ValueInOptArray(int index) { PDFArray opt = Elements.GetArray(Keys.Opt); if (opt != null) { int count = opt.Elements.Count; if (index < 0 || index >= count) { throw new ArgumentOutOfRangeException("index"); } PDFItem item = opt.Elements[index]; if (item is PDFString) { return(item.ToString()); } if (item is PDFArray array) { if (array.Elements.Count != 0) { return(array.Elements[0].ToString()); } } } return(""); }
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]; if (item is PDFReference iref && iref.Value is PDFDictionary) { // The following line is correct! new PDFContent((PDFDictionary)iref.Value); }
/// <summary> /// Unfilters the stream. /// </summary> void Decode() { if (Stream != null && Stream.Value != null) { PDFItem item = Elements["/Filter"]; if (item != null) { byte[] bytes = Filtering.Decode(Stream.Value, item); if (bytes != null) { Stream.Value = bytes; Elements.Remove("/Filter"); Elements.SetInteger("/Length", Stream.Length); } } } }
/// <summary> /// Gets the index of the specified string in the /Opt array or -1, if no such string exists. /// </summary> protected int IndexInOptArray(string value) { PDFArray opt = Elements.GetArray(Keys.Opt); #if DEBUG // Check with //R080317 implemention PDFArray opt2 = null; if (Elements[Keys.Opt] is PDFArray) { opt2 = Elements[Keys.Opt] as PDFArray; } else if (Elements[Keys.Opt] is Advanced.PDFReference) { //falls das Array nicht direkt am Element hängt, //das Array aus dem referenzierten Element holen opt2 = ((Advanced.PDFReference)Elements[Keys.Opt]).Value as PDFArray; } Debug.Assert(ReferenceEquals(opt, opt2)); #endif if (opt != null) { int count = opt.Elements.Count; for (int idx = 0; idx < count; idx++) { PDFItem item = opt.Elements[idx]; if (item is PDFString) { if (item.ToString() == value) { return(idx); } } else if (item is PDFArray array) { if (array.Elements.Count != 0) { if (array.Elements[0].ToString() == value) { return(idx); } } } } } return(-1); }
/// <summary> /// Decodes the data with the specified filter. /// </summary> public static byte[] Decode(byte[] data, PDFItem filterItem) { byte[] result = null; if (filterItem is PDFName) { Filter filter = GetFilter(filterItem.ToString()); if (filter != null) { result = filter.Decode(data); } } else if (filterItem is PDFArray array) { foreach (PDFItem item in array) { data = Decode(data, item); } result = data; } return(result); }
internal PDFFormXObject(PDFDocument thisDocument, PDFImportedObjectTable importedObjectTable, XPDFForm form) : base(thisDocument) { Debug.Assert(importedObjectTable != null); Debug.Assert(ReferenceEquals(thisDocument, importedObjectTable.Owner)); Elements.SetName(Keys.Type, "/XObject"); Elements.SetName(Keys.Subtype, "/Form"); if (form.IsTemplate) { Debug.Assert(importedObjectTable == null); // TODO more initialization here??? return; } XPDFForm pdfForm = form; // Get import page PDFPages importPages = importedObjectTable.ExternalDocument.Pages; if (pdfForm.PageNumber < 1 || pdfForm.PageNumber > importPages.Count) { PSSR.ImportPageNumberOutOfRange(pdfForm.PageNumber, importPages.Count, form._path); } PDFPage importPage = importPages[pdfForm.PageNumber - 1]; // Import resources PDFItem res = importPage.Elements["/Resources"]; if (res != null) // unlikely but possible { #if true // Get root object PDFObject root = res is PDFReference ? ((PDFReference)res).Value : (PDFDictionary)res; root = ImportClosure(importedObjectTable, thisDocument, root); // If the root was a direct object, make it indirect. if (root.Reference == null) { thisDocument.IrefTable.Add(root); } Debug.Assert(root.Reference != null); Elements["/Resources"] = root.Reference; #else // Get transitive closure PDFObject[] resources = importPage.Owner.Internals.GetClosure(resourcesRoot); int count = resources.Length; #if DEBUG_ for (int idx = 0; idx < count; idx++) { Debug.Assert(resources[idx].XRef != null); Debug.Assert(resources[idx].XRef.Document != null); Debug.Assert(resources[idx].Document != null); if (resources[idx].ObjectID.ObjectNumber == 12) { GetType(); } } #endif // 1st step. Already imported objects are reused and new ones are cloned. for (int idx = 0; idx < count; idx++) { PDFObject obj = resources[idx]; if (importedObjectTable.Contains(obj.ObjectID)) { // external object was already imported PDFReference iref = importedObjectTable[obj.ObjectID]; Debug.Assert(iref != null); Debug.Assert(iref.Value != null); Debug.Assert(iref.Document == Owner); // replace external object by the already clone counterpart resources[idx] = iref.Value; } else { // External object was not imported earlier and must be cloned PDFObject clone = obj.Clone(); Debug.Assert(clone.Reference == null); clone.Document = Owner; if (obj.Reference != null) { // add it to this (the importer) document Owner.irefTable.Add(clone); Debug.Assert(clone.Reference != null); // save old object identifier importedObjectTable.Add(obj.ObjectID, clone.Reference); //Debug.WriteLine("Cloned: " + obj.ObjectID.ToString()); } else { // The root object (the /Resources value) is not an indirect object Debug.Assert(idx == 0); // add it to this (the importer) document Owner.irefTable.Add(clone); Debug.Assert(clone.Reference != null); } // replace external object by its clone resources[idx] = clone; } } #if DEBUG_ for (int idx = 0; idx < count; idx++) { Debug.Assert(resources[idx].XRef != null); Debug.Assert(resources[idx].XRef.Document != null); Debug.Assert(resources[idx].Document != null); if (resources[idx].ObjectID.ObjectNumber == 12) { GetType(); } } #endif // 2nd step. Fix up indirect references that still refers to the import document. for (int idx = 0; idx < count; idx++) { PDFObject obj = resources[idx]; Debug.Assert(obj.Owner != null); FixUpObject(importedObjectTable, importedObjectTable.Owner, obj); } // Set resources key to the root of the clones Elements["/Resources"] = resources[0].Reference; #endif } // Take /Rotate into account. PDFRectangle rect = importPage.Elements.GetRectangle(PDFPage.InheritablePageKeys.MediaBox); // Reduce rotation to 0, 90, 180, or 270. int rotate = (importPage.Elements.GetInteger(PDFPage.InheritablePageKeys.Rotate) % 360 + 360) % 360; //rotate = 0; if (rotate == 0) { // Set bounding box to media box. Elements["/BBox"] = rect; } else { // TODO: Have to adjust bounding box? (I think not, but I'm not sure -> wait for problem) Elements["/BBox"] = rect; // Rotate the image such that it is upright. XMatrix matrix = new XMatrix(); double width = rect.Width; double height = rect.Height; matrix.RotateAtPrepend(-rotate, new XPoint(width / 2, height / 2)); // Translate the image such that its center lies on the center of the rotated bounding box. double offset = (height - width) / 2; if (rotate == 90) { // TODO It seems we can simplify this as the sign of offset changes too. if (height > width) { matrix.TranslatePrepend(offset, offset); // Tested. } else { matrix.TranslatePrepend(offset, offset); // TODO Test case. } } else if (rotate == 270) { // TODO It seems we can simplify this as the sign of offset changes too. if (height > width) { matrix.TranslatePrepend(-offset, -offset); // Tested. } else { matrix.TranslatePrepend(-offset, -offset); // Tested. } } //string item = "[" + PDFEncoders.ToString(matrix) + "]"; //Elements[Keys.Matrix] = new PDFLiteral(item); Elements.SetMatrix(Keys.Matrix, matrix); } // Preserve filter because the content keeps unmodified. PDFContent content = importPage.Contents.CreateSingleContent(); #if !DEBUG content.Compressed = true; #endif PDFItem filter = content.Elements["/Filter"]; if (filter != null) { Elements["/Filter"] = filter.Clone(); } // (no cloning needed because the bytes keep untouched) Stream = content.Stream; // new PDFStream(bytes, this); Elements.SetInteger("/Length", content.Stream.Value.Length); }
/// <summary> /// Replace all indirect references to external objects by their cloned counterparts /// owned by the importer document. /// </summary> void FixUpObject_old(PDFImportedObjectTable iot, PDFObject value) { // TODO: merge with PDFXObject.FixUpObject PDFDictionary dict; PDFArray array; if ((dict = value as PDFDictionary) != null) { // Set document for cloned direct objects if (dict.Owner == null) { dict.Document = Owner; } else { Debug.Assert(dict.Owner == Owner); } // Search for indirect references in all keys PDFName[] names = dict.Elements.KeyNames; foreach (PDFName name in names) { PDFItem item = dict.Elements[name]; // Is item an iref? PDFReference iref = item as PDFReference; if (iref != null) { // Does the iref already belong to this document? if (iref.Document == Owner) { // Yes: fine continue; } else { Debug.Assert(iref.Document == iot.ExternalDocument); // No: replace with iref of cloned object PDFReference newXRef = iot[iref.ObjectID]; Debug.Assert(newXRef != null); Debug.Assert(newXRef.Document == Owner); dict.Elements[name] = newXRef; } } else if (item is PDFObject) { // Fix up inner objects FixUpObject_old(iot, (PDFObject)item); } } } else if ((array = value as PDFArray) != null) { // Set document for cloned direct objects if (array.Owner == null) { array.Document = Owner; } else { Debug.Assert(array.Owner == Owner); } // Search for indirect references in all array elements int count = array.Elements.Count; for (int idx = 0; idx < count; idx++) { PDFItem item = array.Elements[idx]; // Is item an iref? PDFReference iref = item as PDFReference; if (iref != null) { // Does the iref belongs to this document? if (iref.Document == Owner) { // Yes: fine continue; } else { Debug.Assert(iref.Document == iot.ExternalDocument); // No: replace with iref of cloned object PDFReference newXRef = iot[iref.ObjectID]; Debug.Assert(newXRef != null); Debug.Assert(newXRef.Document == Owner); array.Elements[idx] = newXRef; } } else if (item is PDFObject) { // Fix up inner objects FixUpObject_old(iot, (PDFObject)item); } } } }
public PDFPreviewControllerDataSource(NSUrl url, string filename) { sources = new PDFItem[1]; sources[0] = new PDFItem(filename, url); }