1
#region PDFsharp - A .NET library for processing PDF
4
// Stefan Lange (mailto:Stefan.Lange@pdfsharp.com)
6
// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
8
// http://www.pdfsharp.com
9
// http://sourceforge.net/projects/pdfsharp
11
// Permission is hereby granted, free of charge, to any person obtaining a
12
// copy of this software and associated documentation files (the "Software"),
13
// to deal in the Software without restriction, including without limitation
14
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
15
// and/or sell copies of the Software, and to permit persons to whom the
16
// Software is furnished to do so, subject to the following conditions:
18
// The above copyright notice and this permission notice shall be included
19
// in all copies or substantial portions of the Software.
21
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27
// DEALINGS IN THE SOFTWARE.
30
// With this define each iref object gets a unique number (uid) to make them distinguishable in the debugger
34
using System.Diagnostics;
35
using System.Collections;
38
using PdfSharp.Internal;
39
using PdfSharp.Pdf.IO;
41
namespace PdfSharp.Pdf.Advanced
44
/// Represents an indirect reference to a PdfObject.
46
[DebuggerDisplay("iref({ObjectNumber}, {GenerationNumber})")]
47
public sealed class PdfReference : PdfItem
51
// * A PdfReference holds the either ObjectID or the PdfObject or both.
53
// * Each PdfObject has a PdfReference if and only if it is an indirect object. Direct objects have
54
// no PdfReference, because they are embedded in a parent objects.
56
// * PdfReference objects are used to reference PdfObject instances. A value in a PDF dictionary
57
// or array that is a PdfReference represents an indirect reference. A value in a PDF dictionary or
58
// or array that is a PdfObject represents a direct (or embeddded) object.
60
// * When a PDF file is imported, the PdfXRefTable is filled with PdfReference objects keeping the
61
// ObjectsIDs and file positions (offsets) of all indirect objects.
63
// * Indirect objects can easily be renumbered because they do not rely on their ObjectsIDs.
65
// * During modification of a document the ObjectID of an indirect object has no meaning,
66
// except that they must be different in pairs.
69
/// Initializes a new PdfReference instance for the specified indirect object.
71
public PdfReference(PdfObject pdfObject)
73
Debug.Assert(pdfObject.Reference == null, "Must not create iref for an object that already has one.");
74
this.value = pdfObject;
75
#if UNIQUE_IREF && DEBUG
76
this.uid = ++PdfReference.counter;
81
/// Initializes a new PdfReference instance from the specified object identifier and file position.
83
public PdfReference(PdfObjectID objectID, int position)
85
this.objectID = objectID;
86
this.position = position;
87
#if UNIQUE_IREF && DEBUG
88
this.uid = ++PdfReference.counter;
93
/// Writes the object in PDF iref table format.
95
internal void WriteXRefEnty(PdfWriter writer)
97
// PDFsharp does not yet support PDF 1.5 object streams.
99
// Each line must be exactly 20 bytes long, otherwise Acrobat repairs the file.
100
string text = String.Format("{0:0000000000} {1:00000} n\n",
101
this.position, this.objectID.GenerationNumber); // this.InUse ? 'n' : 'f');
102
writer.WriteRaw(text);
106
/// Writes an indirect reference.
108
internal override void WriteObject(PdfWriter writer)
114
/// Gets or sets the object identifier.
116
public PdfObjectID ObjectID
118
get { return this.objectID; }
121
if (this.objectID != value)
123
this.objectID = value;
124
if (this.Document != null)
126
//PdfXRefTable table = this.Document.xrefTable;
127
//table.Remove(this);
128
//this.objectID = value;
134
PdfObjectID objectID;
137
/// Gets the object number of the object identifier.
139
public int ObjectNumber
141
get { return this.objectID.ObjectNumber; }
145
/// Gets the generation number of the object identifier.
147
public int GenerationNumber
149
get { return this.objectID.GenerationNumber; }
153
/// Gets or sets the file position of the related PdfObject.
157
get { return this.position; }
158
set { this.position = value; }
160
int position; // I know it should be long, but I have never seen a 2GB PDF file.
164
// get {return this.inUse;}
165
// set {this.inUse = value;}
170
/// Gets or sets the referenced PdfObject.
172
public PdfObject Value
174
get { return this.value; }
178
// value must never be null
179
value.Reference = this;
185
/// Hack for dead objects.
187
internal void SetObject(PdfObject value)
193
/// Gets or sets the document this object belongs to.
195
public PdfDocument Document
197
get { return this.document; }
198
set { this.document = value; }
200
PdfDocument document;
203
/// Gets a string representing the object identifier.
205
public override string ToString()
207
return this.objectID.ToString() + " R";
210
internal static PdfReferenceComparer Comparer
212
get { return new PdfReferenceComparer(); }
216
/// Implements a comparer that compares PdfReference objects by their PdfObjectID.
218
internal class PdfReferenceComparer : IComparer
220
public int Compare(object x, object y)
222
PdfReference l = x as PdfReference;
223
PdfReference r = y as PdfReference;
227
return l.objectID.CompareTo(r.objectID);
238
#if UNIQUE_IREF && DEBUG
239
static int counter = 0;