/** * <summary>Removes the object from its file context.</summary> * <remarks>Only indirect objects can be removed through this method; direct objects have to be * explicitly removed from their parent object. The object is no more usable after this method * returns.</remarks> * <returns>Whether the object was removed from its file context.</returns> */ public virtual bool Delete( ) { PdfIndirectObject indirectObject = IndirectObject; return(indirectObject != null?indirectObject.Delete() : false); }
/** <summary>Instantiates a wrapper in case of reference or mutable data object.</summary> <param name="baseObject">PDF object backing this wrapper. MUST be a <see cref="PdfReference"/> everytime available.</param> */ protected PdfObjectWrapper( PdfDirectObject baseObject ) { BaseObject = baseObject; container = (baseObject != null ? baseObject.Container : null); }
public override PdfObject Visit( PdfIndirectObject obj, object data ) { return(context.IndirectObjects.AddExternal(obj, this)); }
internal Enumerator( NameTree <TValue> nameTree ) { this.nameTree = nameTree; container = nameTree.Container; PdfDictionary rootNode = nameTree.BaseDataObject; PdfDirectObject kidsObject = rootNode[PdfName.Kids]; if (kidsObject == null) // Leaf node. { PdfDirectObject namesObject = rootNode[PdfName.Names]; if (namesObject is PdfReference) { container = ((PdfReference)namesObject).IndirectObject; } names = (PdfArray)File.Resolve(namesObject); } else // Intermediate node. { if (kidsObject is PdfReference) { container = ((PdfReference)kidsObject).IndirectObject; } kids = (PdfArray)File.Resolve(kidsObject); } }
/** * <summary>Adds the <see cref="DataObject">data object</see> to the specified object stream * [PDF:1.6:3.4.6].</summary> * <param name="objectStreamIndirectObject">Target object stream.</param> */ public void Compress( PdfIndirectObject objectStreamIndirectObject ) { if (objectStreamIndirectObject == null) { Uncompress(); } else { PdfDataObject objectStreamDataObject = objectStreamIndirectObject.DataObject; if (!(objectStreamDataObject is ObjectStream)) { throw new ArgumentException("MUST contain an ObjectStream instance.", "objectStreamIndirectObject"); } // Ensure removal from previous object stream! Uncompress(); // Add to the object stream! ObjectStream objectStream = (ObjectStream)objectStreamDataObject; objectStream[xrefEntry.Number] = DataObject; // Update its xref entry! xrefEntry.Usage = XRefEntry.UsageEnum.InUseCompressed; xrefEntry.StreamNumber = objectStreamIndirectObject.Reference.ObjectNumber; xrefEntry.Offset = -1; // Internal object index unknown (to set on object stream serialization -- see ObjectStream). } }
internal Enumerator( Tree <TKey, TValue> tree ) { this.tree = tree; container = tree.Container; PdfDictionary rootNode = tree.BaseDataObject; PdfDirectObject kidsObject = rootNode[PdfName.Kids]; if (kidsObject == null) // Leaf node. { PdfDirectObject namesObject = rootNode[tree.pairsKey]; if (namesObject is PdfReference) { container = ((PdfReference)namesObject).IndirectObject; } names = (PdfArray)namesObject.Resolve(); } else // Intermediate node. { if (kidsObject is PdfReference) { container = ((PdfReference)kidsObject).IndirectObject; } kids = (PdfArray)kidsObject.Resolve(); } }
/** * <param name="baseObject">Base PDF object. MUST be a <see cref="PdfReference"/> * everytime available.</param> * <param name="container">Indirect object containing the base object.</param> */ protected PdfObjectWrapper( PdfDirectObject baseObject, PdfIndirectObject container ) { BaseObject = baseObject; Container = container; }
internal PdfReference( PdfIndirectObject indirectObject ) { this.objectNumber = DelegatedReferenceNumber; this.generationNumber = DelegatedReferenceNumber; this.indirectObject = indirectObject; }
public NameTree( PdfDirectObject baseObject, PdfIndirectObject container ) : base( baseObject, container ) { }
public void Add( PdfArray names, int offset, PdfIndirectObject container ) { keys.Add( (PdfString)names[offset] ); }
internal PdfReference( PdfIndirectObject indirectObject, int objectNumber, int generationNumber ) { this.indirectObject = indirectObject; this.objectNumber = objectNumber; this.generationNumber = generationNumber; }
/** * <param name="baseObject">Base PDF object. MUST be a <see cref="PdfReference"/> * everytime available.</param> * <param name="container">Indirect object containing the base object.</param> * <param name="name">Object name.</param> */ protected PdfNamedObjectWrapper( PdfDirectObject baseObject, PdfIndirectObject container, PdfString name ) : base( baseObject, container ) { this.name = name; }
public virtual PdfObject Visit( PdfIndirectObject obj, object data ) { PdfDataObject dataObject = obj.DataObject; if (dataObject != null) { dataObject.Accept(this, data); } return(obj); }
public override PdfObject Swap( PdfObject other ) { PdfIndirectObject otherObject = (PdfIndirectObject)other; PdfDataObject otherDataObject = otherObject.dataObject; // Update the other! otherObject.DataObject = dataObject; // Update this one! this.DataObject = otherDataObject; return(this); }
public void Add( PdfArray names, int offset, PdfIndirectObject container ) { values.Add( nameTree.Wrap( names[offset + 1], container, (PdfString)names[offset] ) ); }
internal PdfReference( PdfIndirectObject indirectObject ) { this.indirectObject = indirectObject; }
public virtual PdfObject Visit( PdfIndirectObject obj, object data ) { PdfDataObject dataObject = obj.DataObject; if(dataObject != null) {dataObject.Accept(this, data);} return obj; }
public override PdfObject Visit( PdfIndirectObject obj, object data ) { return context.IndirectObjects.AddExternal(obj, this); }
/** <summary>Adds an indirect object entry to the specified xref stream.</summary> <param name="xrefEntry">Indirect object's xref entry.</param> <param name="indirectObject">Indirect object.</param> <param name="xrefStream">XRef stream.</param> <param name="prevFreeEntry">Previous free xref entry.</param> <param name="extensionObjectStreams">Object streams used in incremental updates to extend modified ones.</param> <returns>Current free xref entry.</returns> */ private XRefEntry AddXRefEntry( XRefEntry xrefEntry, PdfIndirectObject indirectObject, XRefStream xrefStream, XRefEntry prevFreeEntry, IDictionary<int,ObjectStream> extensionObjectStreams ) { xrefStream[xrefEntry.Number] = xrefEntry; switch(xrefEntry.Usage) { case XRefEntry.UsageEnum.InUse: { int offset = (int)stream.Length; // Add entry content! indirectObject.WriteTo(stream, file); // Set entry content's offset! xrefEntry.Offset = offset; } break; case XRefEntry.UsageEnum.InUseCompressed: /* NOTE: Serialization is delegated to the containing object stream. */ if(extensionObjectStreams != null) // Incremental update. { int baseStreamNumber = xrefEntry.StreamNumber; PdfIndirectObject baseStreamIndirectObject = file.IndirectObjects[baseStreamNumber]; if(baseStreamIndirectObject.IsOriginal()) // Extension stream needed in order to preserve the original object stream. { // Get the extension object stream associated to the original object stream! ObjectStream extensionObjectStream; if(!extensionObjectStreams.TryGetValue(baseStreamNumber, out extensionObjectStream)) { file.Register(extensionObjectStream = new ObjectStream()); // Link the extension to the base object stream! extensionObjectStream.BaseStream = (ObjectStream)baseStreamIndirectObject.DataObject; extensionObjectStreams[baseStreamNumber] = extensionObjectStream; } // Insert the data object into the extension object stream! extensionObjectStream[xrefEntry.Number] = indirectObject.DataObject; // Update the data object's xref entry! xrefEntry.StreamNumber = extensionObjectStream.Reference.ObjectNumber; xrefEntry.Offset = XRefEntry.UndefinedOffset; // Internal object index unknown (to set on object stream serialization -- see ObjectStream). } } break; case XRefEntry.UsageEnum.Free: if(prevFreeEntry != null) {prevFreeEntry.Offset = xrefEntry.Number;} // Object number of the next free object. prevFreeEntry = xrefEntry; break; default: throw new NotSupportedException(); } return prevFreeEntry; }
/** * <summary>Wraps a base object within its corresponding high-level representation.</summary> */ protected abstract TValue Wrap( PdfDirectObject baseObject, PdfIndirectObject container, PdfString name );
private KeyValuePair <TKey, TValue>?GetNext( ) { /* * NOTE: Algorithm: * 1. [Vertical, down] We have to go downward the name tree till we reach * a names collection (leaf node). * 2. [Horizontal] Then we iterate across the names collection. * 3. [Vertical, up] When leaf-nodes scan is complete, we go upward solving * parent nodes, repeating step 1. */ while (true) { if (names == null) { if (kids == null || kids.Count == levelIndex) // Kids subtree complete. { if (levels.Count == 0) { return(null); } // 3. Go upward one level. // Restore current level! object[] level = levels.Pop(); container = (PdfIndirectObject)level[0]; kids = (PdfArray)level[1]; levelIndex = ((int)level[2]) + 1; // Next node (partially scanned level). } else // Kids subtree incomplete. { // 1. Go downward one level. // Save current level! levels.Push(new object[] { container, kids, levelIndex }); // Move downward! PdfReference kidReference = (PdfReference)kids[levelIndex]; container = kidReference.IndirectObject; PdfDictionary kid = (PdfDictionary)kidReference.DataObject; PdfDirectObject kidsObject = kid[PdfName.Kids]; if (kidsObject == null) // Leaf node. { PdfDirectObject namesObject = kid[tree.pairsKey]; if (namesObject is PdfReference) { container = ((PdfReference)namesObject).IndirectObject; } names = (PdfArray)namesObject.Resolve(); kids = null; } else // Intermediate node. { if (kidsObject is PdfReference) { container = ((PdfReference)kidsObject).IndirectObject; } kids = (PdfArray)kidsObject.Resolve(); } levelIndex = 0; // First node (new level). } } else { if (names.Count == levelIndex) // Names complete. { names = null; } else // Names incomplete. { // 2. Object found. TKey key = (TKey)names[levelIndex]; TValue value = tree.WrapValue(names[levelIndex + 1]); levelIndex += 2; return(new KeyValuePair <TKey, TValue>(key, value)); } } } }