First commit

Send all results
This commit is contained in:
2020-09-04 12:49:15 +05:00
commit 330a2ccfda
2819 changed files with 226201 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
namespace PdfSharp.Pdf
{
/// <summary>
/// Specifies the type of a key's value in a dictionary.
/// </summary>
[Flags]
internal enum KeyType
{
Name = 0x00000001,
String = 0x00000002,
Boolean = 0x00000003,
Integer = 0x00000004,
Real = 0x00000005,
Date = 0x00000006,
Rectangle = 0x00000007,
Array = 0x00000008,
Dictionary = 0x00000009,
Stream = 0x0000000A,
NumberTree = 0x0000000B,
Function = 0x0000000C,
TextString = 0x0000000D,
ByteString = 0x0000000E,
NameOrArray = 0x00000010,
NameOrDictionary = 0x00000020,
ArrayOrDictionary = 0x00000030,
StreamOrArray = 0x00000040,
StreamOrName = 0x00000050,
ArrayOrNameOrString = 0x00000060,
FunctionOrName = 0x000000070,
Various = 0x000000080,
TypeMask = 0x000000FF,
Optional = 0x00000100,
Required = 0x00000200,
Inheritable = 0x00000400,
MustBeIndirect = 0x00001000,
MustNotBeIndirect = 0x00002000,
}
/// <summary>
/// Summary description for KeyInfo.
/// </summary>
internal class KeyInfoAttribute : Attribute
{
public KeyInfoAttribute()
{ }
public KeyInfoAttribute(KeyType keyType)
{
//_version = version;
KeyType = keyType;
}
public KeyInfoAttribute(string version, KeyType keyType)
{
_version = version;
KeyType = keyType;
}
public KeyInfoAttribute(KeyType keyType, Type objectType)
{
//_version = version;
KeyType = keyType;
_objectType = objectType;
}
public KeyInfoAttribute(string version, KeyType keyType, Type objectType)
{
//_version = version;
KeyType = keyType;
_objectType = objectType;
}
public string Version
{
get { return _version; }
set { _version = value; }
}
string _version = "1.0";
public KeyType KeyType
{
get { return _entryType; }
set { _entryType = value; }
}
KeyType _entryType;
public Type ObjectType
{
get { return _objectType; }
set { _objectType = value; }
}
Type _objectType;
public string FixedValue
{
get { return _fixedValue; }
set { _fixedValue = value; }
}
string _fixedValue;
}
}

44
PdfSharp/Pdf/KeysBase.cs Normal file
View File

@@ -0,0 +1,44 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
namespace PdfSharp.Pdf
{
/// <summary>
/// Base class for all dictionary Keys classes.
/// </summary>
public class KeysBase
{
internal static DictionaryMeta CreateMeta(Type type)
{
return new DictionaryMeta(type);
}
}
}

301
PdfSharp/Pdf/KeysMeta.cs Normal file
View File

@@ -0,0 +1,301 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Reflection;
namespace PdfSharp.Pdf
{
/// <summary>
/// Holds information about the value of a key in a dictionary. This information is used to create
/// and interpret this value.
/// </summary>
internal sealed class KeyDescriptor
{
/// <summary>
/// Initializes a new instance of KeyDescriptor from the specified attribute during a KeysMeta
/// initializes itself using reflection.
/// </summary>
public KeyDescriptor(KeyInfoAttribute attribute)
{
_version = attribute.Version;
_keyType = attribute.KeyType;
_fixedValue = attribute.FixedValue;
_objectType = attribute.ObjectType;
if (_version == "")
_version = "1.0";
}
/// <summary>
/// Gets or sets the PDF version starting with the availability of the described key.
/// </summary>
public string Version
{
get { return _version; }
set { _version = value; }
}
string _version;
public KeyType KeyType
{
get { return _keyType; }
set { _keyType = value; }
}
KeyType _keyType;
public string KeyValue
{
get { return _keyValue; }
set { _keyValue = value; }
}
string _keyValue;
public string FixedValue
{
get { return _fixedValue; }
}
readonly string _fixedValue;
public Type ObjectType
{
get { return _objectType; }
set { _objectType = value; }
}
Type _objectType;
public bool CanBeIndirect
{
get { return (_keyType & KeyType.MustNotBeIndirect) == 0; }
}
/// <summary>
/// Returns the type of the object to be created as value for the described key.
/// </summary>
public Type GetValueType()
{
Type type = _objectType;
if (type == null)
{
// If we have no ObjectType specified, use the KeyType enumeration.
switch (_keyType & KeyType.TypeMask)
{
case KeyType.Name:
type = typeof(PdfName);
break;
case KeyType.String:
type = typeof(PdfString);
break;
case KeyType.Boolean:
type = typeof(PdfBoolean);
break;
case KeyType.Integer:
type = typeof(PdfInteger);
break;
case KeyType.Real:
type = typeof(PdfReal);
break;
case KeyType.Date:
type = typeof(PdfDate);
break;
case KeyType.Rectangle:
type = typeof(PdfRectangle);
break;
case KeyType.Array:
type = typeof(PdfArray);
break;
case KeyType.Dictionary:
type = typeof(PdfDictionary);
break;
case KeyType.Stream:
type = typeof(PdfDictionary);
break;
// The following types are not yet used
case KeyType.NumberTree:
throw new NotImplementedException("KeyType.NumberTree");
case KeyType.NameOrArray:
throw new NotImplementedException("KeyType.NameOrArray");
case KeyType.ArrayOrDictionary:
throw new NotImplementedException("KeyType.ArrayOrDictionary");
case KeyType.StreamOrArray:
throw new NotImplementedException("KeyType.StreamOrArray");
case KeyType.ArrayOrNameOrString:
return null; // HACK: Make PdfOutline work
//throw new NotImplementedException("KeyType.ArrayOrNameOrString");
default:
Debug.Assert(false, "Invalid KeyType: " + _keyType);
break;
}
}
return type;
}
}
/// <summary>
/// Contains meta information about all keys of a PDF dictionary.
/// </summary>
internal class DictionaryMeta
{
public DictionaryMeta(Type type)
{
//#if (NETFX_CORE && DEBUG) || CORE
// if (type == typeof(PdfPages.Keys))
// {
// var x = typeof(PdfPages).GetRuntimeFields();
// var y = typeof(PdfPages).GetTypeInfo().DeclaredFields;
// x.GetType();
// y.GetType();
// Debug-Break.Break();
// Test.It();
// }
//#endif
#if !NETFX_CORE && !UWP
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
foreach (FieldInfo field in fields)
{
object[] attributes = field.GetCustomAttributes(typeof(KeyInfoAttribute), false);
if (attributes.Length == 1)
{
KeyInfoAttribute attribute = (KeyInfoAttribute)attributes[0];
KeyDescriptor descriptor = new KeyDescriptor(attribute);
descriptor.KeyValue = (string)field.GetValue(null);
_keyDescriptors[descriptor.KeyValue] = descriptor;
}
}
#else
// Rewritten for WinRT.
CollectKeyDescriptors(type);
//var fields = type.GetRuntimeFields(); // does not work
//fields2.GetType();
//foreach (FieldInfo field in fields)
//{
// var attributes = field.GetCustomAttributes(typeof(KeyInfoAttribute), false);
// foreach (var attribute in attributes)
// {
// KeyDescriptor descriptor = new KeyDescriptor((KeyInfoAttribute)attribute);
// descriptor.KeyValue = (string)field.GetValue(null);
// _keyDescriptors[descriptor.KeyValue] = descriptor;
// }
//}
#endif
}
#if NETFX_CORE || UWP
// Background: The function GetRuntimeFields gets constant fields only for the specified type,
// not for its base types. So we have to walk recursively through base classes.
// The docmentation says full trust for the immediate caller is required for property BaseClass.
// TODO: Rewrite this stuff for medium trust.
void CollectKeyDescriptors(Type type)
{
// Get fields of the specified type only.
var fields = type.GetTypeInfo().DeclaredFields;
foreach (FieldInfo field in fields)
{
var attributes = field.GetCustomAttributes(typeof(KeyInfoAttribute), false);
foreach (var attribute in attributes)
{
KeyDescriptor descriptor = new KeyDescriptor((KeyInfoAttribute)attribute);
descriptor.KeyValue = (string)field.GetValue(null);
_keyDescriptors[descriptor.KeyValue] = descriptor;
}
}
type = type.GetTypeInfo().BaseType;
if (type != typeof(object) && type != typeof(PdfObject))
CollectKeyDescriptors(type);
}
#endif
#if (NETFX_CORE || CORE) && true_
public class A
{
public string _a;
public const string _ca = "x";
}
public class B : A
{
public string _b;
public const string _cb = "x";
void Foo()
{
var str = A._ca;
}
}
class Test
{
public static void It()
{
string s = "Runtime fields of B:";
foreach (var fieldInfo in typeof(B).GetRuntimeFields()) { s += " " + fieldInfo.Name; }
Debug.WriteLine(s);
s = "Declared fields of B:";
foreach (var fieldInfo in typeof(B).GetTypeInfo().DeclaredFields) { s += " " + fieldInfo.Name; }
Debug.WriteLine(s);
s = "Runtime fields of PdfPages.Keys:";
foreach (var fieldInfo in typeof(PdfPages.Keys).GetRuntimeFields()) { s += " " + fieldInfo.Name; }
Debug.WriteLine(s);
}
}
#endif
/// <summary>
/// Gets the KeyDescriptor of the specified key, or null if no such descriptor exits.
/// </summary>
public KeyDescriptor this[string key]
{
get
{
KeyDescriptor keyDescriptor;
_keyDescriptors.TryGetValue(key, out keyDescriptor);
return keyDescriptor;
}
}
readonly Dictionary<string, KeyDescriptor> _keyDescriptors = new Dictionary<string, KeyDescriptor>();
}
}

630
PdfSharp/Pdf/PdfArray.cs Normal file
View File

@@ -0,0 +1,630 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Collections;
using System.Globalization;
using System.Text;
using PdfSharp.Pdf.Advanced;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a PDF array object.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
public class PdfArray : PdfObject, IEnumerable<PdfItem>
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfArray"/> class.
/// </summary>
public PdfArray()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfArray"/> class.
/// </summary>
/// <param name="document">The document.</param>
public PdfArray(PdfDocument document)
: base(document)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfArray"/> class.
/// </summary>
/// <param name="document">The document.</param>
/// <param name="items">The items.</param>
public PdfArray(PdfDocument document, params PdfItem[] items)
: base(document)
{
foreach (PdfItem item in items)
Elements.Add(item);
}
/// <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);
}
/// <summary>
/// Creates a copy of this array. Direct elements are deep copied.
/// Indirect references are not modified.
/// </summary>
public new PdfArray Clone()
{
return (PdfArray)Copy();
}
/// <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;
}
/// <summary>
/// Gets the collection containing the elements of this object.
/// </summary>
public ArrayElements Elements
{
get { return _elements ?? (_elements = new ArrayElements(this)); }
}
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
public virtual IEnumerator<PdfItem> GetEnumerator()
{
return Elements.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Returns a string with the content of this object in a readable form. Useful for debugging purposes only.
/// </summary>
public override string ToString()
{
StringBuilder pdf = new StringBuilder();
pdf.Append("[ ");
int count = Elements.Count;
for (int idx = 0; idx < count; idx++)
pdf.Append(Elements[idx] + " ");
pdf.Append("]");
return pdf.ToString();
}
internal override void WriteObject(PdfWriter writer)
{
writer.WriteBeginObject(this);
int count = Elements.Count;
for (int idx = 0; idx < count; idx++)
{
PdfItem value = Elements[idx];
value.WriteObject(writer);
}
writer.WriteEndObject();
}
/// <summary>
/// Represents the elements of an PdfArray.
/// </summary>
public sealed class ArrayElements : IList<PdfItem>, ICloneable
{
internal ArrayElements(PdfArray array)
{
_elements = new List<PdfItem>();
_ownerArray = array;
}
object ICloneable.Clone()
{
ArrayElements elements = (ArrayElements)MemberwiseClone();
elements._elements = new List<PdfItem>(elements._elements);
elements._ownerArray = null;
return elements;
}
/// <summary>
/// Creates a shallow copy of this object.
/// </summary>
public ArrayElements Clone()
{
return (ArrayElements)((ICloneable)this).Clone();
}
/// <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;
}
/// <summary>
/// Converts the specified value to boolean.
/// If the value does not exist, the function returns false.
/// If the value is not convertible, the function throws an InvalidCastException.
/// If the index is out of range, the function throws an ArgumentOutOfRangeException.
/// </summary>
public bool GetBoolean(int index)
{
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.IndexOutOfRange);
object obj = this[index];
if (obj == null)
return false;
PdfBoolean boolean = obj as PdfBoolean;
if (boolean != null)
return boolean.Value;
PdfBooleanObject booleanObject = obj as PdfBooleanObject;
if (booleanObject != null)
return booleanObject.Value;
throw new InvalidCastException("GetBoolean: Object is not a boolean.");
}
/// <summary>
/// Converts the specified value to integer.
/// If the value does not exist, the function returns 0.
/// If the value is not convertible, the function throws an InvalidCastException.
/// If the index is out of range, the function throws an ArgumentOutOfRangeException.
/// </summary>
public int GetInteger(int index)
{
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.IndexOutOfRange);
object obj = this[index];
if (obj == null)
return 0;
PdfInteger integer = obj as PdfInteger;
if (integer != null)
return integer.Value;
PdfIntegerObject integerObject = obj as PdfIntegerObject;
if (integerObject != null)
return integerObject.Value;
throw new InvalidCastException("GetInteger: Object is not an integer.");
}
/// <summary>
/// Converts the specified value to double.
/// If the value does not exist, the function returns 0.
/// If the value is not convertible, the function throws an InvalidCastException.
/// If the index is out of range, the function throws an ArgumentOutOfRangeException.
/// </summary>
public double GetReal(int index)
{
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.IndexOutOfRange);
object obj = this[index];
if (obj == null)
return 0;
PdfReal real = obj as PdfReal;
if (real != null)
return real.Value;
PdfRealObject realObject = obj as PdfRealObject;
if (realObject != null)
return realObject.Value;
PdfInteger integer = obj as PdfInteger;
if (integer != null)
return integer.Value;
PdfIntegerObject integerObject = obj as PdfIntegerObject;
if (integerObject != null)
return integerObject.Value;
throw new InvalidCastException("GetReal: Object is not a number.");
}
/// <summary>
/// Converts the specified value to double?.
/// If the value does not exist, the function returns null.
/// If the value is not convertible, the function throws an InvalidCastException.
/// If the index is out of range, the function throws an ArgumentOutOfRangeException.
/// </summary>
public double? GetNullableReal(int index)
{
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.IndexOutOfRange);
object obj = this[index];
if (obj == null)
return null;
PdfNull @null = obj as PdfNull;
if (@null != null)
return null;
PdfNullObject nullObject = obj as PdfNullObject;
if (nullObject != null)
return null;
PdfReal real = obj as PdfReal;
if (real != null)
return real.Value;
PdfRealObject realObject = obj as PdfRealObject;
if (realObject != null)
return realObject.Value;
PdfInteger integer = obj as PdfInteger;
if (integer != null)
return integer.Value;
PdfIntegerObject integerObject = obj as PdfIntegerObject;
if (integerObject != null)
return integerObject.Value;
throw new InvalidCastException("GetReal: Object is not a number.");
}
/// <summary>
/// Converts the specified value to string.
/// If the value does not exist, the function returns the empty string.
/// If the value is not convertible, the function throws an InvalidCastException.
/// If the index is out of range, the function throws an ArgumentOutOfRangeException.
/// </summary>
public string GetString(int index)
{
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.IndexOutOfRange);
object obj = this[index];
if (obj == null)
return String.Empty;
PdfString str = obj as PdfString;
if (str != null)
return str.Value;
PdfStringObject strObject = obj as PdfStringObject;
if (strObject != null)
return strObject.Value;
throw new InvalidCastException("GetString: Object is not a string.");
}
/// <summary>
/// Converts the specified value to a name.
/// If the value does not exist, the function returns the empty string.
/// If the value is not convertible, the function throws an InvalidCastException.
/// If the index is out of range, the function throws an ArgumentOutOfRangeException.
/// </summary>
public string GetName(int index)
{
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.IndexOutOfRange);
object obj = this[index];
if (obj == null)
return String.Empty;
PdfName name = obj as PdfName;
if (name != null)
return name.Value;
PdfNameObject nameObject = obj as PdfNameObject;
if (nameObject != null)
return nameObject.Value;
throw new InvalidCastException("GetName: Object is not a name.");
}
/// <summary>
/// Returns the indirect object if the value at the specified index is a PdfReference.
/// </summary>
[Obsolete("Use GetObject, GetDictionary, GetArray, or GetReference")]
public PdfObject GetIndirectObject(int index)
{
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.IndexOutOfRange);
PdfReference reference = this[index] as PdfReference;
if (reference != null)
return reference.Value;
return null;
}
/// <summary>
/// Gets the PdfObject with the specified index, or null, if no such object exists. If the index refers to
/// a reference, the referenced PdfObject is returned.
/// </summary>
public PdfObject GetObject(int index)
{
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.IndexOutOfRange);
PdfItem item = this[index];
PdfReference reference = item as PdfReference;
if (reference != null)
return reference.Value;
return item as PdfObject;
}
/// <summary>
/// Gets the PdfArray with the specified index, or null, if no such object exists. If the index refers to
/// a reference, the referenced PdfArray is returned.
/// </summary>
public PdfDictionary GetDictionary(int index)
{
return GetObject(index) as PdfDictionary;
}
/// <summary>
/// Gets the PdfArray with the specified index, or null, if no such object exists. If the index refers to
/// a reference, the referenced PdfArray is returned.
/// </summary>
public PdfArray GetArray(int index)
{
return GetObject(index) as PdfArray;
}
/// <summary>
/// Gets the PdfReference with the specified index, or null, if no such object exists.
/// </summary>
public PdfReference GetReference(int index)
{
PdfItem item = this[index];
return item as PdfReference;
}
/// <summary>
/// Gets all items of this array.
/// </summary>
public PdfItem[] Items
{
get { return _elements.ToArray(); }
}
#region IList Members
/// <summary>
/// Returns false.
/// </summary>
public bool IsReadOnly
{
get { return false; }
}
/// <summary>
/// Gets or sets an item at the specified index.
/// </summary>
/// <value></value>
public PdfItem this[int index]
{
get { return _elements[index]; }
set
{
if (value == null)
throw new ArgumentNullException("value");
_elements[index] = value;
}
}
/// <summary>
/// Removes the item at the specified index.
/// </summary>
public void RemoveAt(int index)
{
_elements.RemoveAt(index);
}
/// <summary>
/// Removes the first occurrence of a specific object from the array/>.
/// </summary>
public bool Remove(PdfItem item)
{
return _elements.Remove(item);
}
/// <summary>
/// Inserts the item the specified index.
/// </summary>
public void Insert(int index, PdfItem value)
{
_elements.Insert(index, value);
}
/// <summary>
/// Determines whether the specified value is in the array.
/// </summary>
public bool Contains(PdfItem value)
{
return _elements.Contains(value);
}
/// <summary>
/// Removes all items from the array.
/// </summary>
public void Clear()
{
_elements.Clear();
}
/// <summary>
/// Gets the index of the specified item.
/// </summary>
public int IndexOf(PdfItem value)
{
return _elements.IndexOf(value);
}
/// <summary>
/// Appends the specified object to the array.
/// </summary>
public void Add(PdfItem value)
{
// TODO: ???
//Debug.Assert((value is PdfObject && ((PdfObject)value).Reference == null) | !(value is PdfObject),
// "You try to set an indirect object directly into an array.");
PdfObject obj = value as PdfObject;
if (obj != null && obj.IsIndirect)
_elements.Add(obj.Reference);
else
_elements.Add(value);
}
/// <summary>
/// Returns false.
/// </summary>
public bool IsFixedSize
{
get { return false; }
}
#endregion
#region ICollection Members
/// <summary>
/// Returns false.
/// </summary>
public bool IsSynchronized
{
get { return false; }
}
/// <summary>
/// Gets the number of elements in the array.
/// </summary>
public int Count
{
get { return _elements.Count; }
}
/// <summary>
/// Copies the elements of the array to the specified array.
/// </summary>
public void CopyTo(PdfItem[] array, int index)
{
_elements.CopyTo(array, index);
}
/// <summary>
/// The current implementation return null.
/// </summary>
public object SyncRoot
{
get { return null; }
}
#endregion
/// <summary>
/// Returns an enumerator that iterates through the array.
/// </summary>
public IEnumerator<PdfItem> GetEnumerator()
{
return _elements.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _elements.GetEnumerator();
}
/// <summary>
/// The elements of the array.
/// </summary>
List<PdfItem> _elements;
/// <summary>
/// The array this objects belongs to.
/// </summary>
PdfArray _ownerArray;
}
ArrayElements _elements;
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
// ReSharper disable UnusedMember.Local
string DebuggerDisplay
// ReSharper restore UnusedMember.Local
{
get
{
#if true
return String.Format(CultureInfo.InvariantCulture, "array({0},[{1}])", ObjectID.DebuggerDisplay, _elements == null ? 0 : _elements.Count);
#else
return String.Format(CultureInfo.InvariantCulture, "array({0},[{1}])", ObjectID.DebuggerDisplay, _elements == null ? 0 : _elements.Count);
#endif
}
}
}
}

View File

@@ -0,0 +1,91 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System.Diagnostics;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a direct boolean value.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfBoolean : PdfItem
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfBoolean"/> class.
/// </summary>
public PdfBoolean()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfBoolean"/> class.
/// </summary>
public PdfBoolean(bool value)
{
_value = value;
}
/// <summary>
/// Gets the value of this instance as boolean value.
/// </summary>
public bool Value
{
// This class must behave like a value type. Therefore it cannot be changed (like System.String).
get { return _value; }
}
readonly bool _value;
/// <summary>
/// A pre-defined value that represents <c>true</c>.
/// </summary>
public static readonly PdfBoolean True = new PdfBoolean(true);
/// <summary>
/// A pre-defined value that represents <c>false</c>.
/// </summary>
public static readonly PdfBoolean False = new PdfBoolean(false);
/// <summary>
/// Returns 'false' or 'true'.
/// </summary>
public override string ToString()
{
return _value ? bool.TrueString : bool.FalseString;
}
/// <summary>
/// Writes 'true' or 'false'.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.Write(this);
}
}
}

View File

@@ -0,0 +1,94 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System.Diagnostics;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents an indirect boolean value. This type is not used by PDFsharp. If it is imported from
/// an external PDF file, the value is converted into a direct object.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfBooleanObject : PdfObject
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfBooleanObject"/> class.
/// </summary>
public PdfBooleanObject()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfBooleanObject"/> class.
/// </summary>
public PdfBooleanObject(bool value)
{
_value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfBooleanObject"/> class.
/// </summary>
public PdfBooleanObject(PdfDocument document, bool value)
: base(document)
{
_value = value;
}
/// <summary>
/// Gets the value of this instance as boolean value.
/// </summary>
public bool Value
{
get { return _value; }
//set { _value = value; }
}
readonly bool _value;
/// <summary>
/// Returns "false" or "true".
/// </summary>
public override string ToString()
{
return _value ? bool.TrueString : bool.FalseString;
}
/// <summary>
/// Writes the keyword <20>false<73> or <20>true<75>.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.WriteBeginObject(this);
writer.Write(_value);
writer.WriteEndObject();
}
}
}

View File

@@ -0,0 +1,79 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
namespace PdfSharp.Pdf
{
/// <summary>
/// This class is intended for empira internal use only and may change or drop in future releases.
/// </summary>
public class PdfCustomValue : PdfDictionary
{
/// <summary>
/// This function is intended for empira internal use only.
/// </summary>
public PdfCustomValue()
{
CreateStream(new byte[] { });
}
/// <summary>
/// This function is intended for empira internal use only.
/// </summary>
public PdfCustomValue(byte[] bytes)
{
CreateStream(bytes);
}
internal PdfCustomValue(PdfDocument document)
: base(document)
{
CreateStream(new byte[] { });
}
internal PdfCustomValue(PdfDictionary dict)
: base(dict)
{
// TODO: uncompress stream
}
/// <summary>
/// This property is intended for empira internal use only.
/// </summary>
public PdfCustomValueCompressionMode CompressionMode;
/// <summary>
/// This property is intended for empira internal use only.
/// </summary>
public byte[] Value
{
get { return Stream.Value; }
set { Stream.Value = value; }
}
}
}

View File

@@ -0,0 +1,161 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
namespace PdfSharp.Pdf
{
/// <summary>
/// This class is intended for empira internal use only and may change or drop in future releases.
/// </summary>
public class PdfCustomValues : PdfDictionary
{
internal PdfCustomValues()
{ }
internal PdfCustomValues(PdfDocument document)
: base(document)
{ }
internal PdfCustomValues(PdfDictionary dict)
: base(dict)
{ }
/// <summary>
/// This function is intended for empira internal use only.
/// </summary>
public PdfCustomValueCompressionMode CompressionMode
{
set { throw new NotImplementedException(); }
}
/// <summary>
/// This function is intended for empira internal use only.
/// </summary>
public bool Contains(string key)
{
return Elements.ContainsKey(key);
}
/// <summary>
/// This function is intended for empira internal use only.
/// </summary>
public PdfCustomValue this[string key]
{
get
{
PdfDictionary dict = Elements.GetDictionary(key);
if (dict == null)
return null;
PdfCustomValue cust = dict as PdfCustomValue;
if (cust == null)
cust = new PdfCustomValue(dict);
return cust;
}
set
{
if (value == null)
{
Elements.Remove(key);
}
else
{
Owner.Internals.AddObject(value);
Elements.SetReference(key, value);
}
}
#if old
get
{
PdfDictionary dict = Elements.GetDictionary(key);
if (dict == null)
return null;
if (!(dict is PdfCustomValue))
dict = new PdfCustomValue(dict);
return dict.Stream.Value;
}
set
{
PdfCustomValue cust;
PdfDictionary dict = Elements.GetDictionary(key);
if (dict == null)
{
cust = new PdfCustomValue();
Owner.Internals.AddObject(cust);
Elements.Add(key, cust);
}
else
{
cust = dict as PdfCustomValue;
if (cust == null)
cust = new PdfCustomValue(dict);
}
cust.Value = value;
}
#endif
}
/// <summary>
/// This function is intended for empira internal use only.
/// </summary>
public static void ClearAllCustomValues(PdfDocument document)
{
document.CustomValues = null;
foreach (PdfPage page in document.Pages)
page.CustomValues = null;
}
//public static string Key = "/PdfSharp.CustomValue";
internal static PdfCustomValues Get(DictionaryElements elem)
{
string key = elem.Owner.Owner.Internals.CustomValueKey;
PdfCustomValues customValues;
PdfDictionary dict = elem.GetDictionary(key);
if (dict == null)
{
customValues = new PdfCustomValues();
elem.Owner.Owner.Internals.AddObject(customValues);
elem.Add(key, customValues);
}
else
{
customValues = dict as PdfCustomValues;
if (customValues == null)
customValues = new PdfCustomValues(dict);
}
return customValues;
}
internal static void Remove(DictionaryElements elem)
{
elem.Remove(elem.Owner.Owner.Internals.CustomValueKey);
}
}
}

91
PdfSharp/Pdf/PdfDate.cs Normal file
View File

@@ -0,0 +1,91 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a direct date value.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfDate : PdfItem
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfDate"/> class.
/// </summary>
public PdfDate()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfDate"/> class.
/// </summary>
public PdfDate(string value)
{
_value = Parser.ParseDateTime(value, DateTime.MinValue);
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfDate"/> class.
/// </summary>
public PdfDate(DateTime value)
{
_value = value;
}
/// <summary>
/// Gets the value as DateTime.
/// </summary>
public DateTime Value
{
// This class must behave like a value type. Therefore it cannot be changed (like System.String).
get { return _value; }
}
DateTime _value;
/// <summary>
/// Returns the value in the PDF date format.
/// </summary>
public override string ToString()
{
string delta = _value.ToString("zzz").Replace(':', '\'');
return String.Format("D:{0:yyyyMMddHHmmss}{1}'", _value, delta);
}
/// <summary>
/// Writes the value in the PDF date format.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.WriteDocString(ToString());
}
}
}

File diff suppressed because it is too large Load Diff

958
PdfSharp/Pdf/PdfDocument.cs Normal file
View File

@@ -0,0 +1,958 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using System.IO;
#if NETFX_CORE
using System.Threading.Tasks;
#endif
using PdfSharp.Pdf.Advanced;
using PdfSharp.Pdf.Internal;
using PdfSharp.Pdf.IO;
using PdfSharp.Pdf.AcroForms;
using PdfSharp.Pdf.Security;
// ReSharper disable ConvertPropertyToExpressionBody
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a PDF document.
/// </summary>
[DebuggerDisplay("(Name={Name})")] // A name makes debugging easier
public sealed class PdfDocument : PdfObject, IDisposable
{
internal DocumentState _state;
internal PdfDocumentOpenMode _openMode;
#if DEBUG_
static PdfDocument()
{
PSSR.TestResourceMessages();
//string test = PSSR.ResMngr.GetString("SampleMessage1");
//test.GetType();
}
#endif
/// <summary>
/// Creates a new PDF document in memory.
/// To open an existing PDF file, use the PdfReader class.
/// </summary>
public PdfDocument()
{
//PdfDocument.Gob.AttatchDocument(Handle);
_creation = DateTime.Now;
_state = DocumentState.Created;
_version = 14;
Initialize();
Info.CreationDate = _creation;
}
/// <summary>
/// Creates a new PDF document with the specified file name. The file is immediately created and keeps
/// locked until the document is closed, at that time the document is saved automatically.
/// Do not call Save() for documents created with this constructor, just call Close().
/// To open an existing PDF file and import it, use the PdfReader class.
/// </summary>
public PdfDocument(string filename)
{
//PdfDocument.Gob.AttatchDocument(Handle);
_creation = DateTime.Now;
_state = DocumentState.Created;
_version = 14;
Initialize();
Info.CreationDate = _creation;
// TODO 4STLA: encapsulate the whole c'tor with #if !NETFX_CORE?
#if !NETFX_CORE
_outStream = new FileStream(filename, FileMode.Create);
#else
throw new NotImplementedException();
#endif
}
/// <summary>
/// Creates a new PDF document using the specified stream.
/// The stream won't be used until the document is closed, at that time the document is saved automatically.
/// Do not call Save() for documents created with this constructor, just call Close().
/// To open an existing PDF file, use the PdfReader class.
/// </summary>
public PdfDocument(Stream outputStream)
{
//PdfDocument.Gob.AttatchDocument(Handle);
_creation = DateTime.Now;
_state = DocumentState.Created;
Initialize();
Info.CreationDate = _creation;
_outStream = outputStream;
}
internal PdfDocument(Lexer lexer)
{
//PdfDocument.Gob.AttatchDocument(Handle);
_creation = DateTime.Now;
_state = DocumentState.Imported;
//_info = new PdfInfo(this);
//_pages = new PdfPages(this);
//_fontTable = new PdfFontTable();
//_catalog = new PdfCatalog(this);
////_font = new PdfFont();
//_objects = new PdfObjectTable(this);
//_trailer = new PdfTrailer(this);
_irefTable = new PdfCrossReferenceTable(this);
_lexer = lexer;
}
void Initialize()
{
//_info = new PdfInfo(this);
_fontTable = new PdfFontTable(this);
_imageTable = new PdfImageTable(this);
_trailer = new PdfTrailer(this);
_irefTable = new PdfCrossReferenceTable(this);
_trailer.CreateNewDocumentIDs();
}
//~PdfDocument()
//{
// Dispose(false);
//}
/// <summary>
/// Disposes all references to this document stored in other documents. This function should be called
/// for documents you finished importing pages from. Calling Dispose is technically not necessary but
/// useful for earlier reclaiming memory of documents you do not need anymore.
/// </summary>
public void Dispose()
{
Dispose(true);
//GC.SuppressFinalize(this);
}
void Dispose(bool disposing)
{
if (_state != DocumentState.Disposed)
{
if (disposing)
{
// Dispose managed resources.
}
//PdfDocument.Gob.DetatchDocument(Handle);
}
_state = DocumentState.Disposed;
}
/// <summary>
/// Gets or sets a user defined object that contains arbitrary information associated with this document.
/// The tag is not used by PDFsharp.
/// </summary>
public object Tag
{
get { return _tag; }
set { _tag = value; }
}
object _tag;
/// <summary>
/// Gets or sets a value used to distinguish PdfDocument objects.
/// The name is not used by PDFsharp.
/// </summary>
string Name
{
get { return _name; }
set { _name = value; }
}
string _name = NewName();
/// <summary>
/// Get a new default name for a new document.
/// </summary>
static string NewName()
{
#if DEBUG_
if (PdfDocument.nameCount == 57)
PdfDocument.nameCount.GetType();
#endif
return "Document " + _nameCount++;
}
static int _nameCount;
internal bool CanModify
{
//get {return _state == DocumentState.Created || _state == DocumentState.Modifyable;}
get { return true; }
}
/// <summary>
/// Closes this instance.
/// </summary>
public void Close()
{
if (!CanModify)
throw new InvalidOperationException(PSSR.CannotModify);
if (_outStream != null)
{
// Get security handler if document gets encrypted
PdfStandardSecurityHandler securityHandler = null;
if (SecuritySettings.DocumentSecurityLevel != PdfDocumentSecurityLevel.None)
securityHandler = SecuritySettings.SecurityHandler;
PdfWriter writer = new PdfWriter(_outStream, securityHandler);
try
{
DoSave(writer);
}
finally
{
writer.Close();
}
}
}
#if true //!NETFX_CORE
/// <summary>
/// Saves the document to the specified path. If a file already exists, it will be overwritten.
/// </summary>
public void Save(string path)
{
if (!CanModify)
throw new InvalidOperationException(PSSR.CannotModify);
#if !NETFX_CORE
using (Stream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
{
Save(stream);
}
#else
var task = SaveAsync(path, true);
////var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("MyWav.wav", Windows.Storage.CreationCollisionOption.ReplaceExisting);
////var stream = file.OpenStreamForWriteAsync();
////var writer = new StreamWriter(stream);
////Save(stream);
//var ms = new MemoryStream();
//Save(ms, false);
//byte[] pdf = ms.ToArray();
//ms.Close();
#endif
}
#endif
#if NETFX_CORE
/// <summary>
/// Saves the document to the specified path. If a file already exists, it will be overwritten.
/// </summary>
public async Task SaveAsync(string path, bool closeStream)
{
if (!CanModify)
throw new InvalidOperationException(PSSR.CannotModify);
// Just march through...
var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("My1st.pdf", Windows.Storage.CreationCollisionOption.ReplaceExisting);
var stream = await file.OpenStreamForWriteAsync();
using (var writer = new StreamWriter(stream))
{
Save(stream, false);
}
//var ms = new MemoryStream();
//Save(ms, false);
//byte[] pdf = ms.ToArray();
//ms.Close();
//await stream.WriteAsync(pdf, 0, pdf.Length);
//stream.Close();
}
#endif
/// <summary>
/// Saves the document to the specified stream.
/// </summary>
public void Save(Stream stream, bool closeStream)
{
if (!CanModify)
throw new InvalidOperationException(PSSR.CannotModify);
// TODO: more diagnostic checks
string message = "";
if (!CanSave(ref message))
throw new PdfSharpException(message);
// Get security handler if document gets encrypted.
PdfStandardSecurityHandler securityHandler = null;
if (SecuritySettings.DocumentSecurityLevel != PdfDocumentSecurityLevel.None)
securityHandler = SecuritySettings.SecurityHandler;
PdfWriter writer = null;
try
{
writer = new PdfWriter(stream, securityHandler);
DoSave(writer);
}
finally
{
if (stream != null)
{
if (closeStream)
#if UWP
stream.Dispose();
#else
stream.Close();
#endif
else
{
if (stream.CanRead && stream.CanSeek)
stream.Position = 0; // Reset the stream position if the stream is kept open.
}
}
if (writer != null)
writer.Close(closeStream);
}
}
/// <summary>
/// Saves the document to the specified stream.
/// The stream is not closed by this function.
/// (Older versions of PDFsharp closes the stream. That was not very useful.)
/// </summary>
public void Save(Stream stream)
{
Save(stream, false);
}
/// <summary>
/// Implements saving a PDF file.
/// </summary>
void DoSave(PdfWriter writer)
{
if (_pages == null || _pages.Count == 0)
{
if (_outStream != null)
{
// Give feedback if the wrong constructor was used.
throw new InvalidOperationException("Cannot save a PDF document with no pages. Do not use \"public PdfDocument(string filename)\" or \"public PdfDocument(Stream outputStream)\" if you want to open an existing PDF document from a file or stream; use PdfReader.Open() for that purpose.");
}
throw new InvalidOperationException("Cannot save a PDF document with no pages.");
}
try
{
// HACK: Remove XRefTrailer
if (_trailer is PdfCrossReferenceStream)
{
// HACK^2: Preserve the SecurityHandler.
PdfStandardSecurityHandler securityHandler = _securitySettings.SecurityHandler;
_trailer = new PdfTrailer((PdfCrossReferenceStream)_trailer);
_trailer._securityHandler = securityHandler;
}
bool encrypt = _securitySettings.DocumentSecurityLevel != PdfDocumentSecurityLevel.None;
if (encrypt)
{
PdfStandardSecurityHandler securityHandler = _securitySettings.SecurityHandler;
if (securityHandler.Reference == null)
_irefTable.Add(securityHandler);
else
Debug.Assert(_irefTable.Contains(securityHandler.ObjectID));
_trailer.Elements[PdfTrailer.Keys.Encrypt] = _securitySettings.SecurityHandler.Reference;
}
else
_trailer.Elements.Remove(PdfTrailer.Keys.Encrypt);
PrepareForSave();
if (encrypt)
_securitySettings.SecurityHandler.PrepareEncryption();
writer.WriteFileHeader(this);
PdfReference[] irefs = _irefTable.AllReferences;
int count = irefs.Length;
for (int idx = 0; idx < count; idx++)
{
PdfReference iref = irefs[idx];
#if DEBUG_
if (iref.ObjectNumber == 378)
GetType();
#endif
iref.Position = writer.Position;
iref.Value.WriteObject(writer);
}
int startxref = writer.Position;
_irefTable.WriteObject(writer);
writer.WriteRaw("trailer\n");
_trailer.Elements.SetInteger("/Size", count + 1);
_trailer.WriteObject(writer);
writer.WriteEof(this, startxref);
//if (encrypt)
//{
// state &= ~DocumentState.SavingEncrypted;
// //_securitySettings.SecurityHandler.EncryptDocument();
//}
}
finally
{
if (writer != null)
{
writer.Stream.Flush();
// DO NOT CLOSE WRITER HERE
//writer.Close();
}
}
}
/// <summary>
/// Dispatches PrepareForSave to the objects that need it.
/// </summary>
internal override void PrepareForSave()
{
PdfDocumentInformation info = Info;
// Add patch level to producer if it is not '0'.
string pdfSharpProducer = VersionInfo.Producer;
if (!ProductVersionInfo.VersionPatch.Equals("0"))
pdfSharpProducer = ProductVersionInfo.Producer2;
// Set Creator if value is undefined.
if (info.Elements[PdfDocumentInformation.Keys.Creator] == null)
info.Creator = pdfSharpProducer;
// Keep original producer if file was imported.
string producer = info.Producer;
if (producer.Length == 0)
producer = pdfSharpProducer;
else
{
// Prevent endless concatenation if file is edited with PDFsharp more than once.
if (!producer.StartsWith(VersionInfo.Title))
producer = pdfSharpProducer + " (Original: " + producer + ")";
}
info.Elements.SetString(PdfDocumentInformation.Keys.Producer, producer);
// Prepare used fonts.
if (_fontTable != null)
_fontTable.PrepareForSave();
// Let catalog do the rest.
Catalog.PrepareForSave();
#if true
// Remove all unreachable objects (e.g. from deleted pages)
int removed = _irefTable.Compact();
if (removed != 0)
Debug.WriteLine("PrepareForSave: Number of deleted unreachable objects: " + removed);
_irefTable.Renumber();
#endif
}
/// <summary>
/// Determines whether the document can be saved.
/// </summary>
public bool CanSave(ref string message)
{
if (!SecuritySettings.CanSave(ref message))
return false;
return true;
}
internal bool HasVersion(string version)
{
return String.Compare(Catalog.Version, version) >= 0;
}
/// <summary>
/// Gets the document options used for saving the document.
/// </summary>
public PdfDocumentOptions Options
{
get
{
if (_options == null)
_options = new PdfDocumentOptions(this);
return _options;
}
}
PdfDocumentOptions _options;
/// <summary>
/// Gets PDF specific document settings.
/// </summary>
public PdfDocumentSettings Settings
{
get
{
if (_settings == null)
_settings = new PdfDocumentSettings(this);
return _settings;
}
}
PdfDocumentSettings _settings;
/// <summary>
/// NYI Indicates whether large objects are written immediately to the output stream to relieve
/// memory consumption.
/// </summary>
internal bool EarlyWrite
{
get { return false; }
}
/// <summary>
/// Gets or sets the PDF version number. Return value 14 e.g. means PDF 1.4 / Acrobat 5 etc.
/// </summary>
public int Version
{
get { return _version; }
set
{
if (!CanModify)
throw new InvalidOperationException(PSSR.CannotModify);
if (value < 12 || value > 17) // TODO not really implemented
throw new ArgumentException(PSSR.InvalidVersionNumber, "value");
_version = value;
}
}
internal int _version;
/// <summary>
/// Gets the number of pages in the document.
/// </summary>
public int PageCount
{
get
{
if (CanModify)
return Pages.Count;
// PdfOpenMode is InformationOnly
PdfDictionary pageTreeRoot = (PdfDictionary)Catalog.Elements.GetObject(PdfCatalog.Keys.Pages);
return pageTreeRoot.Elements.GetInteger(PdfPages.Keys.Count);
}
}
/// <summary>
/// Gets the file size of the document.
/// </summary>
public long FileSize
{
get { return _fileSize; }
}
internal long _fileSize; // TODO: make private
/// <summary>
/// Gets the full qualified file name if the document was read form a file, or an empty string otherwise.
/// </summary>
public string FullPath
{
get { return _fullPath; }
}
internal string _fullPath = String.Empty; // TODO: make private
/// <summary>
/// Gets a Guid that uniquely identifies this instance of PdfDocument.
/// </summary>
public Guid Guid
{
get { return _guid; }
}
Guid _guid = Guid.NewGuid();
internal DocumentHandle Handle
{
get
{
if (_handle == null)
_handle = new DocumentHandle(this);
return _handle;
}
}
DocumentHandle _handle;
/// <summary>
/// Returns a value indicating whether the document was newly created or opened from an existing document.
/// Returns true if the document was opened with the PdfReader.Open function, false otherwise.
/// </summary>
public bool IsImported
{
get { return (_state & DocumentState.Imported) != 0; }
}
/// <summary>
/// Returns a value indicating whether the document is read only or can be modified.
/// </summary>
public bool IsReadOnly
{
get { return (_openMode != PdfDocumentOpenMode.Modify); }
}
internal Exception DocumentNotImported()
{
return new InvalidOperationException("Document not imported.");
}
/// <summary>
/// Gets information about the document.
/// </summary>
public PdfDocumentInformation Info
{
get
{
if (_info == null)
_info = _trailer.Info;
return _info;
}
}
PdfDocumentInformation _info; // never changes if once created
/// <summary>
/// This function is intended to be undocumented.
/// </summary>
public PdfCustomValues CustomValues
{
get
{
if (_customValues == null)
_customValues = PdfCustomValues.Get(Catalog.Elements);
return _customValues;
}
set
{
if (value != null)
throw new ArgumentException("Only null is allowed to clear all custom values.");
PdfCustomValues.Remove(Catalog.Elements);
_customValues = null;
}
}
PdfCustomValues _customValues;
/// <summary>
/// Get the pages dictionary.
/// </summary>
public PdfPages Pages
{
get
{
if (_pages == null)
_pages = Catalog.Pages;
return _pages;
}
}
PdfPages _pages; // never changes if once created
/// <summary>
/// Gets or sets a value specifying the page layout to be used when the document is opened.
/// </summary>
public PdfPageLayout PageLayout
{
get { return Catalog.PageLayout; }
set
{
if (!CanModify)
throw new InvalidOperationException(PSSR.CannotModify);
Catalog.PageLayout = value;
}
}
/// <summary>
/// Gets or sets a value specifying how the document should be displayed when opened.
/// </summary>
public PdfPageMode PageMode
{
get { return Catalog.PageMode; }
set
{
if (!CanModify)
throw new InvalidOperationException(PSSR.CannotModify);
Catalog.PageMode = value;
}
}
/// <summary>
/// Gets the viewer preferences of this document.
/// </summary>
public PdfViewerPreferences ViewerPreferences
{
get { return Catalog.ViewerPreferences; }
}
/// <summary>
/// Gets the root of the outline (or bookmark) tree.
/// </summary>
public PdfOutlineCollection Outlines
{
get { return Catalog.Outlines; }
}
/// <summary>
/// Get the AcroForm dictionary.
/// </summary>
public PdfAcroForm AcroForm
{
get { return Catalog.AcroForm; }
}
/// <summary>
/// Gets or sets the default language of the document.
/// </summary>
public string Language
{
get { return Catalog.Language; }
set { Catalog.Language = value; }
}
/// <summary>
/// Gets the security settings of this document.
/// </summary>
public PdfSecuritySettings SecuritySettings
{
get { return _securitySettings ?? (_securitySettings = new PdfSecuritySettings(this)); }
}
internal PdfSecuritySettings _securitySettings;
/// <summary>
/// Gets the document font table that holds all fonts used in the current document.
/// </summary>
internal PdfFontTable FontTable
{
get { return _fontTable ?? (_fontTable = new PdfFontTable(this)); }
}
PdfFontTable _fontTable;
/// <summary>
/// Gets the document image table that holds all images used in the current document.
/// </summary>
internal PdfImageTable ImageTable
{
get
{
if (_imageTable == null)
_imageTable = new PdfImageTable(this);
return _imageTable;
}
}
PdfImageTable _imageTable;
/// <summary>
/// Gets the document form table that holds all form external objects used in the current document.
/// </summary>
internal PdfFormXObjectTable FormTable // TODO: Rename to ExternalDocumentTable.
{
get { return _formTable ?? (_formTable = new PdfFormXObjectTable(this)); }
}
PdfFormXObjectTable _formTable;
/// <summary>
/// Gets the document ExtGState table that holds all form state objects used in the current document.
/// </summary>
internal PdfExtGStateTable ExtGStateTable
{
get { return _extGStateTable ?? (_extGStateTable = new PdfExtGStateTable(this)); }
}
PdfExtGStateTable _extGStateTable;
/// <summary>
/// Gets the PdfCatalog of the current document.
/// </summary>
internal PdfCatalog Catalog
{
get { return _catalog ?? (_catalog = _trailer.Root); }
}
PdfCatalog _catalog; // never changes if once created
/// <summary>
/// Gets the PdfInternals object of this document, that grants access to some internal structures
/// which are not part of the public interface of PdfDocument.
/// </summary>
public new PdfInternals Internals
{
get { return _internals ?? (_internals = new PdfInternals(this)); }
}
PdfInternals _internals;
/// <summary>
/// Creates a new page and adds it to this document.
/// Depending of the IsMetric property of the current region the page size is set to
/// A4 or Letter respectively. If this size is not appropriate it should be changed before
/// any drawing operations are performed on the page.
/// </summary>
public PdfPage AddPage()
{
if (!CanModify)
throw new InvalidOperationException(PSSR.CannotModify);
return Catalog.Pages.Add();
}
/// <summary>
/// Adds the specified page to this document. If the page is from an external document,
/// it is imported to this document. In this case the returned page is not the same
/// object as the specified one.
/// </summary>
public PdfPage AddPage(PdfPage page)
{
if (!CanModify)
throw new InvalidOperationException(PSSR.CannotModify);
return Catalog.Pages.Add(page);
}
/// <summary>
/// Creates a new page and inserts it in this document at the specified position.
/// </summary>
public PdfPage InsertPage(int index)
{
if (!CanModify)
throw new InvalidOperationException(PSSR.CannotModify);
return Catalog.Pages.Insert(index);
}
/// <summary>
/// Inserts the specified page in this document. If the page is from an external document,
/// it is imported to this document. In this case the returned page is not the same
/// object as the specified one.
/// </summary>
public PdfPage InsertPage(int index, PdfPage page)
{
if (!CanModify)
throw new InvalidOperationException(PSSR.CannotModify);
return Catalog.Pages.Insert(index, page);
}
/// <summary>
/// Flattens a document (make the fields non-editable).
/// </summary>
public void Flatten()
{
for (int idx = 0; idx < AcroForm.Fields.Count; idx++)
{
AcroForm.Fields[idx].ReadOnly = true;
}
}
/// <summary>
/// Gets the security handler.
/// </summary>
public PdfStandardSecurityHandler SecurityHandler
{
get { return _trailer.SecurityHandler; }
}
internal PdfTrailer _trailer;
internal PdfCrossReferenceTable _irefTable;
internal Stream _outStream;
// Imported Document
internal Lexer _lexer;
internal DateTime _creation;
/// <summary>
/// Occurs when the specified document is not used anymore for importing content.
/// </summary>
internal void OnExternalDocumentFinalized(PdfDocument.DocumentHandle handle)
{
if (tls != null)
{
//PdfDocument[] documents = tls.Documents;
tls.DetachDocument(handle);
}
if (_formTable != null)
_formTable.DetachDocument(handle);
}
//internal static GlobalObjectTable Gob = new GlobalObjectTable();
/// <summary>
/// Gets the ThreadLocalStorage object. It is used for caching objects that should created
/// only once.
/// </summary>
internal static ThreadLocalStorage Tls
{
get { return tls ?? (tls = new ThreadLocalStorage()); }
}
[ThreadStatic]
static ThreadLocalStorage tls;
[DebuggerDisplay("(ID={ID}, alive={IsAlive})")]
internal class DocumentHandle
{
public DocumentHandle(PdfDocument document)
{
_weakRef = new WeakReference(document);
ID = document._guid.ToString("B").ToUpper();
}
public bool IsAlive
{
get { return _weakRef.IsAlive; }
}
public PdfDocument Target
{
get { return _weakRef.Target as PdfDocument; }
}
readonly WeakReference _weakRef;
public string ID;
public override bool Equals(object obj)
{
DocumentHandle handle = obj as DocumentHandle;
if (!ReferenceEquals(handle, null))
return ID == handle.ID;
return false;
}
public override int GetHashCode()
{
return ID.GetHashCode();
}
public static bool operator ==(DocumentHandle left, DocumentHandle right)
{
if (ReferenceEquals(left, null))
return ReferenceEquals(right, null);
return left.Equals(right);
}
public static bool operator !=(DocumentHandle left, DocumentHandle right)
{
return !(left == right);
}
}
}
}

View File

@@ -0,0 +1,207 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents the PDF document information dictionary.
/// </summary>
public sealed class PdfDocumentInformation : PdfDictionary
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfDocumentInformation"/> class.
/// </summary>
public PdfDocumentInformation(PdfDocument document)
: base(document)
{ }
internal PdfDocumentInformation(PdfDictionary dict)
: base(dict)
{ }
/// <summary>
/// Gets or sets the document's title.
/// </summary>
public string Title
{
get { return Elements.GetString(Keys.Title); }
set { Elements.SetString(Keys.Title, value); }
}
/// <summary>
/// Gets or sets the name of the person who created the document.
/// </summary>
public string Author
{
get { return Elements.GetString(Keys.Author); }
set { Elements.SetString(Keys.Author, value); }
}
/// <summary>
/// Gets or sets the name of the subject of the document.
/// </summary>
public string Subject
{
get { return Elements.GetString(Keys.Subject); }
set { Elements.SetString(Keys.Subject, value); }
}
/// <summary>
/// Gets or sets keywords associated with the document.
/// </summary>
public string Keywords
{
get { return Elements.GetString(Keys.Keywords); }
set { Elements.SetString(Keys.Keywords, value); }
}
/// <summary>
/// Gets or sets the name of the application (for example, MigraDoc) that created the document.
/// </summary>
public string Creator
{
get { return Elements.GetString(Keys.Creator); }
set { Elements.SetString(Keys.Creator, value); }
}
/// <summary>
/// Gets the producer application (for example, PDFsharp).
/// </summary>
public string Producer
{
get { return Elements.GetString(Keys.Producer); }
}
/// <summary>
/// Gets or sets the creation date of the document.
/// Breaking Change: If the date is not set in a PDF file DateTime.MinValue is returned.
/// </summary>
public DateTime CreationDate
{
get { return Elements.GetDateTime(Keys.CreationDate, DateTime.MinValue); }
set { Elements.SetDateTime(Keys.CreationDate, value); }
}
/// <summary>
/// Gets or sets the modification date of the document.
/// Breaking Change: If the date is not set in a PDF file DateTime.MinValue is returned.
/// </summary>
public DateTime ModificationDate
{
get { return Elements.GetDateTime(Keys.ModDate, DateTime.MinValue); }
set { Elements.SetDateTime(Keys.ModDate, value); }
}
// TODO CustomProperties and meta data
/// <summary>
/// Predefined keys of this dictionary.
/// </summary>
internal sealed class Keys : KeysBase
{
/// <summary>
/// (Optional; PDF 1.1) The document<6E>s title.
/// </summary>
[KeyInfo(KeyType.String | KeyType.Optional)]
public const string Title = "/Title";
/// <summary>
/// (Optional) The name of the person who created the document.
/// </summary>
[KeyInfo(KeyType.String | KeyType.Optional)]
public const string Author = "/Author";
/// <summary>
/// (Optional; PDF 1.1) The subject of the document.
/// </summary>
[KeyInfo(KeyType.String | KeyType.Optional)]
public const string Subject = "/Subject";
/// <summary>
/// (Optional; PDF 1.1) Keywords associated with the document.
/// </summary>
[KeyInfo(KeyType.String | KeyType.Optional)]
public const string Keywords = "/Keywords";
/// <summary>
/// (Optional) If the document was converted to PDF from another format,
/// the name of the application (for example, empira MigraDoc) that created the
/// original document from which it was converted.
/// </summary>
[KeyInfo(KeyType.String | KeyType.Optional)]
public const string Creator = "/Creator";
/// <summary>
/// (Optional) If the document was converted to PDF from another format,
/// the name of the application (for example, this library) that converted it to PDF.
/// </summary>
[KeyInfo(KeyType.String | KeyType.Optional)]
public const string Producer = "/Producer";
/// <summary>
/// (Optional) The date and time the document was created, in human-readable form.
/// </summary>
[KeyInfo(KeyType.Date | KeyType.Optional)]
public const string CreationDate = "/CreationDate";
/// <summary>
/// (Required if PieceInfo is present in the document catalog; otherwise optional; PDF 1.1)
/// The date and time the document was most recently modified, in human-readable form.
/// </summary>
[KeyInfo(KeyType.String | KeyType.Optional)]
public const string ModDate = "/ModDate";
/// <summary>
/// (Optional; PDF 1.3) A name object indicating whether the document has been modified
/// to include trapping information.
/// </summary>
[KeyInfo("1.3", KeyType.Name | KeyType.Optional)]
public const string Trapped = "/Trapped";
/// <summary>
/// Gets the KeysMeta for these keys.
/// </summary>
public static DictionaryMeta Meta
{
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
}
static DictionaryMeta _meta;
}
/// <summary>
/// Gets the KeysMeta of this dictionary type.
/// </summary>
internal override DictionaryMeta Meta
{
get { return Keys.Meta; }
}
}
}

View File

@@ -0,0 +1,111 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
// ReSharper disable ConvertToAutoProperty
namespace PdfSharp.Pdf
{
/// <summary>
/// Holds information how to handle the document when it is saved as PDF stream.
/// </summary>
public sealed class PdfDocumentOptions
{
internal PdfDocumentOptions(PdfDocument document)
{
//_deflateContents = true;
//_writeProcedureSets = true;
}
/// <summary>
/// Gets or sets the color mode.
/// </summary>
public PdfColorMode ColorMode
{
get { return _colorMode; }
set { _colorMode = value; }
}
PdfColorMode _colorMode = PdfColorMode.Rgb;
/// <summary>
/// Gets or sets a value indicating whether to compress content streams of PDF pages.
/// </summary>
public bool CompressContentStreams
{
get { return _compressContentStreams; }
set { _compressContentStreams = value; }
}
#if DEBUG
bool _compressContentStreams = false;
#else
bool _compressContentStreams = true;
#endif
/// <summary>
/// Gets or sets a value indicating that all objects are not compressed.
/// </summary>
public bool NoCompression
{
get { return _noCompression; }
set { _noCompression = value; }
}
bool _noCompression;
/// <summary>
/// Gets or sets the flate encode mode. Besides the balanced default mode you can set modes for best compression (slower) or best speed (larger files).
/// </summary>
public PdfFlateEncodeMode FlateEncodeMode
{
get { return _flateEncodeMode; }
set { _flateEncodeMode = value; }
}
PdfFlateEncodeMode _flateEncodeMode = PdfFlateEncodeMode.Default;
/// <summary>
/// Gets or sets a value indicating whether to compress bilevel images using CCITT compression.
/// With true, PDFsharp will try FlateDecode CCITT and will use the smallest one or a combination of both.
/// With false, PDFsharp will always use FlateDecode only - files may be a few bytes larger, but file creation is faster.
/// </summary>
public bool EnableCcittCompressionForBilevelImages
{
get { return _enableCcittCompressionForBilevelImages; }
set { _enableCcittCompressionForBilevelImages = value; }
}
bool _enableCcittCompressionForBilevelImages = false;
/// <summary>
/// Gets or sets a value indicating whether to compress JPEG images with the FlateDecode filter.
/// </summary>
public PdfUseFlateDecoderForJpegImages UseFlateDecoderForJpegImages
{
get { return _useFlateDecoderForJpegImages; }
set { _useFlateDecoderForJpegImages = value; }
}
PdfUseFlateDecoderForJpegImages _useFlateDecoderForJpegImages = PdfUseFlateDecoderForJpegImages.Never;
}
}

View File

@@ -0,0 +1,68 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
namespace PdfSharp.Pdf
{
/// <summary>
/// Holds PDF specific information of the document.
/// </summary>
public sealed class PdfDocumentSettings
{
internal PdfDocumentSettings(PdfDocument document)
{ }
/// <summary>
/// Gets or sets the default trim margins.
/// </summary>
public TrimMargins TrimMargins
{
get
{
if (_trimMargins == null)
_trimMargins = new TrimMargins();
return _trimMargins;
}
set
{
if (_trimMargins == null)
_trimMargins = new TrimMargins();
if (value != null)
{
_trimMargins.Left = value.Left;
_trimMargins.Right = value.Right;
_trimMargins.Top = value.Top;
_trimMargins.Bottom = value.Bottom;
}
else
_trimMargins.All = 0;
}
}
TrimMargins _trimMargins = new TrimMargins();
}
}

178
PdfSharp/Pdf/PdfInteger.cs Normal file
View File

@@ -0,0 +1,178 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using System.Globalization;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a direct integer value.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfInteger : PdfNumber, IConvertible
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfInteger"/> class.
/// </summary>
public PdfInteger()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfInteger"/> class.
/// </summary>
/// <param name="value">The value.</param>
public PdfInteger(int value)
{
_value = value;
}
/// <summary>
/// Gets the value as integer.
/// </summary>
public int Value
{
// This class must behave like a value type. Therefore it cannot be changed (like System.String).
get { return _value; }
}
readonly int _value;
/// <summary>
/// Returns the integer as string.
/// </summary>
public override string ToString()
{
return _value.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Writes the integer as string.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.Write(this);
}
#region IConvertible Members
ulong IConvertible.ToUInt64(IFormatProvider provider)
{
return Convert.ToUInt64(_value);
}
sbyte IConvertible.ToSByte(IFormatProvider provider)
{
throw new InvalidCastException();
}
double IConvertible.ToDouble(IFormatProvider provider)
{
return _value;
}
DateTime IConvertible.ToDateTime(IFormatProvider provider)
{
// TODO: Add PdfInteger.ToDateTime implementation
return new DateTime();
}
float IConvertible.ToSingle(IFormatProvider provider)
{
return _value;
}
bool IConvertible.ToBoolean(IFormatProvider provider)
{
return Convert.ToBoolean(_value);
}
int IConvertible.ToInt32(IFormatProvider provider)
{
return _value;
}
ushort IConvertible.ToUInt16(IFormatProvider provider)
{
return Convert.ToUInt16(_value);
}
short IConvertible.ToInt16(IFormatProvider provider)
{
return Convert.ToInt16(_value);
}
string IConvertible.ToString(IFormatProvider provider)
{
return _value.ToString(provider);
}
byte IConvertible.ToByte(IFormatProvider provider)
{
return Convert.ToByte(_value);
}
char IConvertible.ToChar(IFormatProvider provider)
{
return Convert.ToChar(_value);
}
long IConvertible.ToInt64(IFormatProvider provider)
{
return _value;
}
/// <summary>
/// Returns TypeCode for 32-bit integers.
/// </summary>
public TypeCode GetTypeCode()
{
return TypeCode.Int32;
}
decimal IConvertible.ToDecimal(IFormatProvider provider)
{
return _value;
}
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
{
// TODO: Add PdfInteger.ToType implementation
return null;
}
uint IConvertible.ToUInt32(IFormatProvider provider)
{
return Convert.ToUInt32(_value);
}
#endregion
}
}

View File

@@ -0,0 +1,94 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System.Diagnostics;
using System.Globalization;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents an indirect integer value. This type is not used by PDFsharp. If it is imported from
/// an external PDF file, the value is converted into a direct object.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfIntegerObject : PdfNumberObject
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfIntegerObject"/> class.
/// </summary>
public PdfIntegerObject()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfIntegerObject"/> class.
/// </summary>
public PdfIntegerObject(int value)
{
_value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfIntegerObject"/> class.
/// </summary>
public PdfIntegerObject(PdfDocument document, int value)
: base(document)
{
_value = value;
}
/// <summary>
/// Gets the value as integer.
/// </summary>
public int Value
{
get { return _value; }
//set {_value = value;}
}
readonly int _value;
/// <summary>
/// Returns the integer as string.
/// </summary>
public override string ToString()
{
return _value.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Writes the integer literal.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.WriteBeginObject(this);
writer.Write(_value);
writer.WriteEndObject();
}
}
}

69
PdfSharp/Pdf/PdfItem.cs Normal file
View File

@@ -0,0 +1,69 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// The base class of all PDF objects and simple PDF types.
/// </summary>
public abstract class PdfItem : ICloneable
{
// All simple types (i.e. derived from PdfItem but not from PdfObject) must be immutable.
object ICloneable.Clone()
{
return Copy();
}
/// <summary>
/// Creates a copy of this object.
/// </summary>
public PdfItem Clone()
{
return (PdfItem)Copy();
}
/// <summary>
/// Implements the copy mechanism. Must be overridden in derived classes.
/// </summary>
protected virtual object Copy()
{
return MemberwiseClone();
}
/// <summary>
/// When overridden in a derived class, appends a raw string representation of this object
/// to the specified PdfWriter.
/// </summary>
internal abstract void WriteObject(PdfWriter writer);
}
}

101
PdfSharp/Pdf/PdfLiteral.cs Normal file
View File

@@ -0,0 +1,101 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections;
using System.Globalization;
using System.Text;
using System.IO;
using PdfSharp.Drawing;
using PdfSharp.Internal;
using PdfSharp.Pdf.IO;
using PdfSharp.Pdf.Internal;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents text that is written 'as it is' into the PDF stream. This class can lead to invalid PDF files.
/// E.g. strings in a literal are not encrypted when the document is saved with a password.
/// </summary>
public sealed class PdfLiteral : PdfItem
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfLiteral"/> class.
/// </summary>
public PdfLiteral()
{ }
/// <summary>
/// Initializes a new instance with the specified string.
/// </summary>
public PdfLiteral(string value)
{
_value = value;
}
/// <summary>
/// Initializes a new instance with the culture invariant formatted specified arguments.
/// </summary>
public PdfLiteral(string format, params object[] args)
{
_value = PdfEncoders.Format(format, args);
}
/// <summary>
/// Creates a literal from an XMatrix
/// </summary>
public static PdfLiteral FromMatrix(XMatrix matrix)
{
return new PdfLiteral("[" + PdfEncoders.ToString(matrix) + "]");
}
/// <summary>
/// Gets the value as litaral string.
/// </summary>
public string Value
{
// This class must behave like a value type. Therefore it cannot be changed (like System.String).
get { return _value; }
}
readonly string _value = String.Empty;
/// <summary>
/// Returns a string that represents the current value.
/// </summary>
public override string ToString()
{
return _value;
}
internal override void WriteObject(PdfWriter writer)
{
writer.Write(this);
}
}
}

170
PdfSharp/Pdf/PdfName.cs Normal file
View File

@@ -0,0 +1,170 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-20165 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a PDF name value.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfName : PdfItem
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfName"/> class.
/// </summary>
public PdfName()
{
_value = "/"; // Empty name.
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfName"/> class.
/// Parameter value always must start with a '/'.
/// </summary>
public PdfName(string value)
{
if (value == null)
throw new ArgumentNullException("value");
if (value.Length == 0 || value[0] != '/')
throw new ArgumentException(PSSR.NameMustStartWithSlash);
_value = value;
}
/// <summary>
/// Determines whether the specified object is equal to this name.
/// </summary>
public override bool Equals(object obj)
{
return _value.Equals(obj);
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
public override int GetHashCode()
{
return _value.GetHashCode();
}
/// <summary>
/// Gets the name as a string.
/// </summary>
public string Value
{
// This class must behave like a value type. Therefore it cannot be changed (like System.String).
get { return _value; }
}
readonly string _value;
/// <summary>
/// Returns the name. The string always begins with a slash.
/// </summary>
public override string ToString()
{
return _value;
}
/// <summary>
/// Determines whether the specified name and string are equal.
/// </summary>
public static bool operator ==(PdfName name, string str)
{
if (ReferenceEquals(name, null))
return str == null;
return name._value == str;
}
/// <summary>
/// Determines whether the specified name and string are not equal.
/// </summary>
public static bool operator !=(PdfName name, string str)
{
if (ReferenceEquals(name, null))
return str != null;
return name._value != str;
}
/// <summary>
/// Represents the empty name.
/// </summary>
public static readonly PdfName Empty = new PdfName("/");
/// <summary>
/// Writes the name including the leading slash.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
// TODO: what if unicode character are part of the name?
writer.Write(this);
}
/// <summary>
/// Gets the comparer for this type.
/// </summary>
public static PdfXNameComparer Comparer
{
get { return new PdfXNameComparer(); }
}
/// <summary>
/// Implements a comparer that compares PdfName objects.
/// </summary>
public class PdfXNameComparer : IComparer<PdfName>
{
/// <summary>
/// Compares two objects and returns a value indicating whether one is less than, equal to, or greater than the other.
/// </summary>
/// <param name="l">The first object to compare.</param>
/// <param name="r">The second object to compare.</param>
public int Compare(PdfName l, PdfName r)
{
#if true_
#else
if (l != null)
{
if (r != null)
return String.Compare(l._value, r._value, StringComparison.Ordinal);
return -1;
}
if (r != null)
return 1;
return 0;
#endif
}
}
}
}

View File

@@ -0,0 +1,151 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents an indirect name value. This type is not used by PDFsharp. If it is imported from
/// an external PDF file, the value is converted into a direct object. Acrobat sometime uses indirect
/// names to save space, because an indirect reference to a name may be shorter than a long name.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfNameObject : PdfObject
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfNameObject"/> class.
/// </summary>
public PdfNameObject()
{
_value = "/"; // Empty name.
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfNameObject"/> class.
/// </summary>
/// <param name="document">The document.</param>
/// <param name="value">The value.</param>
public PdfNameObject(PdfDocument document, string value)
: base(document)
{
if (value == null)
throw new ArgumentNullException("value");
if (value.Length == 0 || value[0] != '/')
throw new ArgumentException(PSSR.NameMustStartWithSlash);
_value = value;
}
/// <summary>
/// Determines whether the specified object is equal to the current object.
/// </summary>
public override bool Equals(object obj)
{
return _value.Equals(obj);
}
/// <summary>
/// Serves as a hash function for this type.
/// </summary>
public override int GetHashCode()
{
return _value.GetHashCode();
}
/// <summary>
/// Gets or sets the name value.
/// </summary>
public string Value
{
get { return _value; }
set { _value = value; }
}
string _value;
/// <summary>
/// Returns the name. The string always begins with a slash.
/// </summary>
public override string ToString()
{
// TODO: Encode characters.
return _value;
}
/// <summary>
/// Determines whether a name is equal to a string.
/// </summary>
public static bool operator ==(PdfNameObject name, string str)
{
return name._value == str;
}
/// <summary>
/// Determines whether a name is not equal to a string.
/// </summary>
public static bool operator !=(PdfNameObject name, string str)
{
return name._value != str;
}
#if leads_to_ambiguity
public static bool operator ==(string str, PdfName name)
{
return str == name.value;
}
public static bool operator !=(string str, PdfName name)
{
return str == name.value;
}
public static bool operator ==(PdfName name1, PdfName name2)
{
return name1.value == name2.value;
}
public static bool operator !=(PdfName name1, PdfName name2)
{
return name1.value != name2.value;
}
#endif
/// <summary>
/// Writes the name including the leading slash.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.WriteBeginObject(this);
writer.Write(new PdfName(_value));
writer.WriteEndObject();
}
}
}

66
PdfSharp/Pdf/PdfNull.cs Normal file
View File

@@ -0,0 +1,66 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a indirect reference that is not in the cross reference table.
/// </summary>
public sealed class PdfNull : PdfItem
{
// Reference: 3.2.8 Null Object / Page 63
PdfNull()
{ }
/// <summary>
/// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
/// </returns>
public override string ToString()
{
return "null";
}
internal override void WriteObject(PdfWriter writer)
{
// Implementet because it must be overridden.
writer.WriteRaw(" null ");
}
/// <summary>
/// The only instance of this class.
/// </summary>
public static readonly PdfNull Value = new PdfNull();
}
}

View File

@@ -0,0 +1,74 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents an indirect null value. This type is not used by PDFsharp, but at least
/// one tool from Adobe creates PDF files with a null object.
/// </summary>
public sealed class PdfNullObject : PdfObject
{
// Reference: 3.2.8 Null Object / Page 63
/// <summary>
/// Initializes a new instance of the <see cref="PdfNullObject"/> class.
/// </summary>
public PdfNullObject()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfNullObject"/> class.
/// </summary>
/// <param name="document">The document.</param>
public PdfNullObject(PdfDocument document)
: base(document)
{ }
/// <summary>
/// Returns the string "null".
/// </summary>
public override string ToString()
{
return "null";
}
/// <summary>
/// Writes the keyword <20>null<6C>.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.WriteBeginObject(this);
writer.WriteRaw(" null ");
writer.WriteEndObject();
}
}
}

39
PdfSharp/Pdf/PdfNumber.cs Normal file
View File

@@ -0,0 +1,39 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
namespace PdfSharp.Pdf
{
/// <summary>
/// Base class for direct number values (not yet used, maybe superfluous).
/// </summary>
public abstract class PdfNumber : PdfItem
{
// No code in base class.
}
}

View File

@@ -0,0 +1,51 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
namespace PdfSharp.Pdf
{
/// <summary>
/// Base class for indirect number values (not yet used, maybe superfluous).
/// </summary>
public abstract class PdfNumberObject : PdfObject
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfNumberObject"/> class.
/// </summary>
protected PdfNumberObject()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfNumberObject"/> class.
/// </summary>
/// <param name="document">The document.</param>
protected PdfNumberObject(PdfDocument document)
: base(document)
{ }
}
}

602
PdfSharp/Pdf/PdfObject.cs Normal file
View File

@@ -0,0 +1,602 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using PdfSharp.Pdf.Advanced;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Base class of all composite PDF objects.
/// </summary>
public abstract class PdfObject : PdfItem
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfObject"/> class.
/// </summary>
protected PdfObject()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfObject"/> class.
/// </summary>
protected PdfObject(PdfDocument document)
{
// Calling a virtual member in a constructor is dangerous.
// In PDFsharp Document is overridden in PdfPage and the code is checked to be save
// when called for a not completely initialized object.
Document = document;
}
/// <summary>
/// Initializes a new instance from an existing object. Used for object type transformation.
/// </summary>
protected PdfObject(PdfObject obj)
: this(obj.Owner)
{
// If the object that was transformed to an instance of a derived class was an indirect object
// set the value of the reference to this.
if (obj._iref != null)
obj._iref.Value = this;
#if DEBUG_ // BUG
else
{
// If this occurs it is an internal error
Debug.Assert(false, "Object type transformation must not be done with direct objects");
}
#endif
}
/// <summary>
/// Creates a copy of this object. The clone does not belong to a document, i.e. its owner and its iref are null.
/// </summary>
public new PdfObject Clone()
{
return (PdfObject)Copy();
}
/// <summary>
/// Implements the copy mechanism. Must be overridden in derived classes.
/// </summary>
protected override object Copy()
{
PdfObject obj = (PdfObject)base.Copy();
obj._document = null;
obj._iref = null;
return obj;
}
#if true_ // works, but may lead to other problems that I cannot assess
/// <summary>
/// Determines whether the specified object is equal to the current PdfObject.
/// </summary>
public override bool Equals(object obj)
{
if (obj is PdfObject)
{
PdfObject other = (PdfObject)obj;
// Take object type transformation into account
if (_iref != null && other._iref != null)
{
Debug.Assert(_iref.Value != null, "iref without value.");
Debug.Assert(other.iref.Value != null, "iref without value.");
return Object.ReferenceEquals(_iref.Value, other.iref.Value);
}
}
return base.Equals(obj);
}
public override int GetHashCode()
{
if (_iref != null)
{
Debug.Assert(_iref.Value != null, "iref without value.");
return _iref.GetHashCode();
}
return base.GetHashCode();
}
#endif
/// <summary>
/// Sets the object and generation number.
/// Setting the object identifier makes this object an indirect object, i.e. the object gets
/// a PdfReference entry in the PdfReferenceTable.
/// </summary>
internal void SetObjectID(int objectNumber, int generationNumber)
{
PdfObjectID objectID = new PdfObjectID(objectNumber, generationNumber);
// TODO: check imported
if (_iref == null)
_iref = _document._irefTable[objectID];
if (_iref == null)
{
// ReSharper disable once ObjectCreationAsStatement because the new object is set to this object
// in the constructor of PdfReference.
new PdfReference(this);
Debug.Assert(_iref != null);
_iref.ObjectID = objectID;
}
_iref.Value = this;
_iref.Document = _document;
}
/// <summary>
/// Gets the PdfDocument this object belongs to.
/// </summary>
public virtual PdfDocument Owner
{
get { return _document; }
}
/// <summary>
/// Sets the PdfDocument this object belongs to.
/// </summary>
internal virtual PdfDocument Document
{
set
{
if (!ReferenceEquals(_document, value))
{
if (_document != null)
throw new InvalidOperationException("Cannot change document.");
_document = value;
if (_iref != null)
_iref.Document = value;
}
}
}
internal PdfDocument _document;
/// <summary>
/// Indicates whether the object is an indirect object.
/// </summary>
public bool IsIndirect
{
// An object is an indirect object if and only if is has an indirect reference value.
get { return _iref != null; }
}
/// <summary>
/// Gets the PdfInternals object of this document, that grants access to some internal structures
/// which are not part of the public interface of PdfDocument.
/// </summary>
public PdfObjectInternals Internals
{
get { return _internals ?? (_internals = new PdfObjectInternals(this)); }
}
PdfObjectInternals _internals;
/// <summary>
/// When overridden in a derived class, prepares the object to get saved.
/// </summary>
internal virtual void PrepareForSave()
{ }
/// <summary>
/// Saves the stream position. 2nd Edition.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
Debug.Assert(false, "Must not come here!");
//Debug.Assert(_inStreamOffset <= 0);
//if (_inStreamOffset == 0)
//{
// //_InStreamOffset = stream.Position;
// _document.xrefTable.AddObject(this);
// return Format("{0} {1} obj\n", _objectID, _generation);
//}
//else if (_inStreamOffset == -1)
//{
//}
//return null;
}
/// <summary>
/// Gets the object identifier. Returns PdfObjectID.Empty for direct objects,
/// i.e. never returns null.
/// </summary>
internal PdfObjectID ObjectID
{
get { return _iref != null ? _iref.ObjectID : PdfObjectID.Empty; }
}
/// <summary>
/// Gets the object number.
/// </summary>
internal int ObjectNumber
{
get { return ObjectID.ObjectNumber; }
}
/// <summary>
/// Gets the generation number.
/// </summary>
internal int GenerationNumber
{
get { return ObjectID.GenerationNumber; }
}
///// <summary>
///// Creates a deep copy of the specified value and its transitive closure and adds the
///// new objects to the specified owner document.
///// </summary>
/// <param name="owner">The document that owns the cloned objects.</param>
/// <param name="externalObject">The root object to be cloned.</param>
/// <returns>The clone of the root object</returns>
internal static PdfObject DeepCopyClosure(PdfDocument owner, PdfObject externalObject)
{
// Get transitive closure.
PdfObject[] elements = externalObject.Owner.Internals.GetClosure(externalObject);
int count = elements.Length;
#if DEBUG_
for (int idx = 0; idx < count; idx++)
{
Debug.Assert(elements[idx].XRef != null);
Debug.Assert(elements[idx].XRef.Document != null);
Debug.Assert(elements[idx].Document != null);
if (elements[idx].ObjectID.ObjectNumber == 12)
GetType();
}
#endif
// 1st loop. Replace all objects by their clones.
PdfImportedObjectTable iot = new PdfImportedObjectTable(owner, externalObject.Owner);
for (int idx = 0; idx < count; idx++)
{
PdfObject obj = elements[idx];
PdfObject clone = obj.Clone();
Debug.Assert(clone.Reference == null);
clone.Document = owner;
if (obj.Reference != null)
{
// Case: The cloned object was an indirect object.
// Add clone to new owner document.
owner._irefTable.Add(clone);
// The clone gets an iref by adding it to its new owner.
Debug.Assert(clone.Reference != null);
// Save an association from old object identifier to new iref.
iot.Add(obj.ObjectID, clone.Reference);
}
else
{
// Case: The cloned object was an direct object.
// Only the root object can be a direct object.
Debug.Assert(idx == 0);
}
// Replace external object by its clone.
elements[idx] = clone;
}
#if DEBUG_
for (int idx = 0; idx < count; idx++)
{
Debug.Assert(elements[idx]._iref != null);
Debug.Assert(elements[idx]._iref.Document != null);
Debug.Assert(resources[idx].Document != null);
if (elements[idx].ObjectID.ObjectNumber == 12)
GetType();
}
#endif
// 2nd loop. Fix up all indirect references that still refers to the import document.
for (int idx = 0; idx < count; idx++)
{
PdfObject obj = elements[idx];
Debug.Assert(obj.Owner == owner);
FixUpObject(iot, owner, obj);
}
// Return the clone of the former root object.
return elements[0];
}
///// <summary>
///// Imports an object and its transitive closure to the specified document.
///// </summary>
/// <param name="importedObjectTable">The imported object table of the owner for the external document.</param>
/// <param name="owner">The document that owns the cloned objects.</param>
/// <param name="externalObject">The root object to be cloned.</param>
/// <returns>The clone of the root object</returns>
internal static PdfObject ImportClosure(PdfImportedObjectTable importedObjectTable, PdfDocument owner, PdfObject externalObject)
{
Debug.Assert(ReferenceEquals(importedObjectTable.Owner, owner), "importedObjectTable does not belong to the owner.");
Debug.Assert(ReferenceEquals(importedObjectTable.ExternalDocument, externalObject.Owner),
"The ExternalDocument of the importedObjectTable does not belong to the owner of object to be imported.");
// Get transitive closure of external object.
PdfObject[] elements = externalObject.Owner.Internals.GetClosure(externalObject);
int count = elements.Length;
#if DEBUG_
for (int idx = 0; idx < count; idx++)
{
Debug.Assert(elements[idx].XRef != null);
Debug.Assert(elements[idx].XRef.Document != null);
Debug.Assert(elements[idx].Document != null);
if (elements[idx].ObjectID.ObjectNumber == 12)
GetType();
}
#endif
// 1st loop. Already imported objects are reused and new ones are cloned.
for (int idx = 0; idx < count; idx++)
{
PdfObject obj = elements[idx];
Debug.Assert(!ReferenceEquals(obj.Owner, owner));
if (importedObjectTable.Contains(obj.ObjectID))
{
#if DEBUG_
if (obj.ObjectID.ObjectNumber == 5894)
obj.GetType();
#endif
// Case: 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 cloned counterpart.
elements[idx] = iref.Value;
}
else
{
// Case: External object was not yet imported earlier and must be cloned.
PdfObject clone = obj.Clone();
Debug.Assert(clone.Reference == null);
clone.Document = owner;
if (obj.Reference != null)
{
// Case: The cloned object was an indirect object.
// Add clone to new owner document.
owner._irefTable.Add(clone);
Debug.Assert(clone.Reference != null);
// Save an association from old object identifier to new iref.
importedObjectTable.Add(obj.ObjectID, clone.Reference);
}
else
{
// Case: The cloned object was a direct object.
// Only the root object can be a direct object.
Debug.Assert(idx == 0);
}
// Replace external object by its clone.
elements[idx] = clone;
}
}
#if DEBUG_
for (int idx = 0; idx < count; idx++)
{
//Debug.Assert(elements[idx].Reference != null);
//Debug.Assert(elements[idx].Reference.Document != null);
Debug.Assert(elements[idx].IsIndirect == false);
Debug.Assert(elements[idx].Owner != null);
//if (elements[idx].ObjectID.ObjectNumber == 12)
// GetType();
}
#endif
// 2nd loop. Fix up indirect references that still refers to the external document.
for (int idx = 0; idx < count; idx++)
{
PdfObject obj = elements[idx];
Debug.Assert(owner != null);
FixUpObject(importedObjectTable, importedObjectTable.Owner, obj);
}
// Return the imported root object.
return elements[0];
}
/// <summary>
/// Replace all indirect references to external objects by their cloned counterparts
/// owned by the importer document.
/// </summary>
static void FixUpObject(PdfImportedObjectTable iot, PdfDocument owner, PdfObject value)
{
Debug.Assert(ReferenceEquals(iot.Owner, owner));
PdfDictionary dict;
PdfArray array;
if ((dict = value as PdfDictionary) != null)
{
// Case: The object is a dictionary.
// Set document for cloned direct objects.
if (dict.Owner == null)
{
// If the dictionary has not yet an owner set the owner to the importing document.
dict.Document = owner;
}
else
{
// If the dictionary already has an owner it must be the importing document.
Debug.Assert(dict.Owner == owner);
}
// Search for indirect references in all dictionary elements.
PdfName[] names = dict.Elements.KeyNames;
foreach (PdfName name in names)
{
PdfItem item = dict.Elements[name];
Debug.Assert(item != null, "A dictionary element cannot be null.");
// Is item an iref?
PdfReference iref = item as PdfReference;
if (iref != null)
{
// Case: The item is a reference.
// Does the iref already belongs to the new owner?
if (iref.Document == owner)
{
// Yes: fine. Happens when an already cloned object is reused.
continue;
}
//Debug.Assert(iref.Document == iot.Document);
// No: Replace with iref of cloned object.
PdfReference newXRef = iot[iref.ObjectID]; // TODO: Explain this line of code in all details.
Debug.Assert(newXRef != null);
Debug.Assert(newXRef.Document == owner);
dict.Elements[name] = newXRef;
}
else
{
// Case: The item is not a reference.
// If item is an object recursively fix its inner items.
PdfObject pdfObject = item as PdfObject;
if (pdfObject != null)
{
// Fix up inner objects, i.e. recursively walk down the object tree.
FixUpObject(iot, owner, pdfObject);
}
else
{
// The item is something else, e.g. a name.
// Nothing to do.
// ...but let's double check this case in DEBUG build.
DebugCheckNonObjects(item);
}
}
}
}
else if ((array = value as PdfArray) != null)
{
// Case: The object is an array.
// Set document for cloned direct objects.
if (array.Owner == null)
{
// If the array has not yet an owner set the owner to the importing document.
array.Document = owner;
}
else
{
// If the array already has an owner it must be the importing document.
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];
Debug.Assert(item != null, "An array element cannot be null.");
// Is item an iref?
PdfReference iref = item as PdfReference;
if (iref != null)
{
// Case: The item is a reference.
// Does the iref already belongs to the owner?
if (iref.Document == owner)
{
// Yes: fine. Happens when an already cloned object is reused.
continue;
}
// No: replace with iref of cloned object.
Debug.Assert(iref.Document == iot.ExternalDocument);
PdfReference newXRef = iot[iref.ObjectID];
Debug.Assert(newXRef != null);
Debug.Assert(newXRef.Document == owner);
array.Elements[idx] = newXRef;
}
else
{
// Case: The item is not a reference.
// If item is an object recursively fix its inner items.
PdfObject pdfObject = item as PdfObject;
if (pdfObject != null)
{
// Fix up inner objects, i.e. recursively walk down the object tree.
FixUpObject(iot, owner, pdfObject);
}
else
{
// The item is something else, e.g. a name.
// Nothing to do.
// ...but let's double check this case in DEBUG build.
DebugCheckNonObjects(item);
}
}
}
}
else
{
// Case: The item is some other indirect object.
// Indirect integers, booleans, etc. are allowed, but PDFsharp do not create them.
// If such objects occur in imported PDF files from other producers, nothing more is to do.
// The owner was already set, which is double checked by the assertions below.
if (value is PdfNameObject || value is PdfStringObject || value is PdfBooleanObject || value is PdfIntegerObject || value is PdfNumberObject)
{
Debug.Assert(value.IsIndirect);
Debug.Assert(value.Owner == owner);
}
else
Debug.Assert(false, "Should not come here. Object is neither a dictionary nor an array.");
}
}
/// <summary>
/// Ensure for future versions of PDFsharp not to forget code for a new kind of PdfItem.
/// </summary>
/// <param name="item">The item.</param>
[Conditional("DEBUG")]
static void DebugCheckNonObjects(PdfItem item)
{
if (item is PdfName)
return;
if (item is PdfBoolean)
return;
if (item is PdfInteger)
return;
if (item is PdfNumber)
return;
if (item is PdfString)
return;
if (item is PdfRectangle)
return;
if (item is PdfNull)
return;
Type type = item.GetType();
Debug.Assert(type != null, string.Format("CheckNonObjects: Add {0} to the list.", type.Name));
}
/// <summary>
/// Gets the indirect reference of this object. If the value is null, this object is a direct object.
/// </summary>
public PdfReference Reference
{
get { return _iref; }
// Setting the reference outside PDFsharp is not considered as a valid operation.
internal set { _iref = value; }
}
PdfReference _iref;
}
}

179
PdfSharp/Pdf/PdfObjectID.cs Normal file
View File

@@ -0,0 +1,179 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using System.Globalization;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a PDF object identifier, a pair of object and generation number.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
public struct PdfObjectID : IComparable
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfObjectID"/> class.
/// </summary>
/// <param name="objectNumber">The object number.</param>
public PdfObjectID(int objectNumber)
{
Debug.Assert(objectNumber >= 1, "Object number out of range.");
_objectNumber = objectNumber;
_generationNumber = 0;
#if DEBUG_
// Just a place for a breakpoint during debugging.
if (objectNumber == 5894)
GetType();
#endif
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfObjectID"/> class.
/// </summary>
/// <param name="objectNumber">The object number.</param>
/// <param name="generationNumber">The generation number.</param>
public PdfObjectID(int objectNumber, int generationNumber)
{
Debug.Assert(objectNumber >= 1, "Object number out of range.");
//Debug.Assert(generationNumber >= 0 && generationNumber <= 65535, "Generation number out of range.");
#if DEBUG_
// iText creates generation numbers with a value of 65536...
if (generationNumber > 65535)
Debug.WriteLine(String.Format("Generation number: {0}", generationNumber));
#endif
_objectNumber = objectNumber;
_generationNumber = (ushort)generationNumber;
}
/// <summary>
/// Gets or sets the object number.
/// </summary>
public int ObjectNumber
{
get { return _objectNumber; }
}
readonly int _objectNumber;
/// <summary>
/// Gets or sets the generation number.
/// </summary>
public int GenerationNumber
{
get { return _generationNumber; }
}
readonly ushort _generationNumber;
/// <summary>
/// Indicates whether this object is an empty object identifier.
/// </summary>
public bool IsEmpty
{
get { return _objectNumber == 0; }
}
/// <summary>
/// Indicates whether this instance and a specified object are equal.
/// </summary>
public override bool Equals(object obj)
{
if (obj is PdfObjectID)
{
PdfObjectID id = (PdfObjectID)obj;
if (_objectNumber == id._objectNumber)
return _generationNumber == id._generationNumber;
}
return false;
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
public override int GetHashCode()
{
return _objectNumber ^ _generationNumber;
}
/// <summary>
/// Determines whether the two objects are equal.
/// </summary>
public static bool operator ==(PdfObjectID left, PdfObjectID right)
{
return left.Equals(right);
}
/// <summary>
/// Determines whether the tow objects not are equal.
/// </summary>
public static bool operator !=(PdfObjectID left, PdfObjectID right)
{
return !left.Equals(right);
}
/// <summary>
/// Returns the object and generation numbers as a string.
/// </summary>
public override string ToString()
{
return _objectNumber.ToString(CultureInfo.InvariantCulture) + " " + _generationNumber.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Creates an empty object identifier.
/// </summary>
public static PdfObjectID Empty
{
get { return new PdfObjectID(); }
}
/// <summary>
/// Compares the current object id with another object.
/// </summary>
public int CompareTo(object obj)
{
if (obj is PdfObjectID)
{
PdfObjectID id = (PdfObjectID)obj;
if (_objectNumber == id._objectNumber)
return _generationNumber - id._generationNumber;
return _objectNumber - id._objectNumber;
}
return 1;
}
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
internal string DebuggerDisplay
{
get { return String.Format("id=({0})", ToString()); }
}
}
}

836
PdfSharp/Pdf/PdfOutline.cs Normal file
View File

@@ -0,0 +1,836 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2018 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
// Review: Under construction - StL/14-10-05
using System;
using System.Diagnostics;
using System.Globalization;
using System.Text;
using PdfSharp.Drawing;
using PdfSharp.Pdf.Actions;
using PdfSharp.Pdf.Advanced;
using PdfSharp.Pdf.IO;
using PdfSharp.Pdf.Internal;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents an outline item in the outlines tree. An 'outline' is also known as a 'bookmark'.
/// </summary>
public sealed class PdfOutline : PdfDictionary
{
// Reference: 8.2.2<EFBFBD><EFBFBD>Document Outline / Page 584
/// <summary>
/// Initializes a new instance of the <see cref="PdfOutline"/> class.
/// </summary>
public PdfOutline()
{
// Create _outlines on demand.
//_outlines = new PdfOutlineCollection(this);
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfOutline"/> class.
/// </summary>
/// <param name="document">The document.</param>
internal PdfOutline(PdfDocument document)
: base(document)
{
// Create _outlines on demand.
//_outlines = new PdfOutlineCollection(this);
}
/// <summary>
/// Initializes a new instance from an existing dictionary. Used for object type transformation.
/// </summary>
public PdfOutline(PdfDictionary dict)
: base(dict)
{
Initialize();
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfOutline"/> class.
/// </summary>
/// <param name="title">The outline text.</param>
/// <param name="destinationPage">The destination page.</param>
/// <param name="opened">Specifies whether the node is displayed expanded (opened) or collapsed.</param>
/// <param name="style">The font style used to draw the outline text.</param>
/// <param name="textColor">The color used to draw the outline text.</param>
public PdfOutline(string title, PdfPage destinationPage, bool opened, PdfOutlineStyle style, XColor textColor)
{
Title = title;
DestinationPage = destinationPage;
Opened = opened;
Style = style;
TextColor = textColor;
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfOutline"/> class.
/// </summary>
/// <param name="title">The outline text.</param>
/// <param name="destinationPage">The destination page.</param>
/// <param name="opened">Specifies whether the node is displayed expanded (opened) or collapsed.</param>
/// <param name="style">The font style used to draw the outline text.</param>
public PdfOutline(string title, PdfPage destinationPage, bool opened, PdfOutlineStyle style)
{
Title = title;
DestinationPage = destinationPage;
Opened = opened;
Style = style;
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfOutline"/> class.
/// </summary>
/// <param name="title">The outline text.</param>
/// <param name="destinationPage">The destination page.</param>
/// <param name="opened">Specifies whether the node is displayed expanded (opened) or collapsed.</param>
public PdfOutline(string title, PdfPage destinationPage, bool opened)
{
Title = title;
DestinationPage = destinationPage;
Opened = opened;
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfOutline"/> class.
/// </summary>
/// <param name="title">The outline text.</param>
/// <param name="destinationPage">The destination page.</param>
public PdfOutline(string title, PdfPage destinationPage)
{
Title = title;
DestinationPage = destinationPage;
}
internal int Count
{
get { return _count; }
set { _count = value; }
}
int _count;
/// <summary>
/// The total number of open descendants at all lower levels.
/// </summary>
internal int OpenCount;
/// <summary>
/// Counts the open outline items. Not yet used.
/// </summary>
internal int CountOpen()
{
int count = _opened ? 1 : 0;
if (_outlines != null)
count += _outlines.CountOpen();
return count;
}
/// <summary>
/// Gets the parent of this outline item. The root item has no parent and returns null.
/// </summary>
public PdfOutline Parent
{
get { return _parent; }
internal set { _parent = value; }
}
PdfOutline _parent;
/// <summary>
/// Gets or sets the title.
/// </summary>
public string Title
{
get { return Elements.GetString(Keys.Title); }
set
{
PdfString s = new PdfString(value, PdfStringEncoding.Unicode);
Elements.SetValue(Keys.Title, s);
}
}
/// <summary>
/// Gets or sets the destination page.
/// </summary>
public PdfPage DestinationPage
{
get { return _destinationPage; }
set { _destinationPage = value; }
}
PdfPage _destinationPage;
/// <summary>
/// Gets or sets the left position of the page positioned at the left side of the window.
/// Applies only if PageDestinationType is Xyz, FitV, FitR, or FitBV.
/// </summary>
public double? Left
{
get { return _left; }
set { _left = value; }
}
double? _left = null;
/// <summary>
/// Gets or sets the top position of the page positioned at the top side of the window.
/// Applies only if PageDestinationType is Xyz, FitH, FitR, ob FitBH.
/// </summary>
public double? Top
{
get { return _top; }
set { _top = value; }
}
double? _top = null;
/// <summary>
/// Gets or sets the right position of the page positioned at the right side of the window.
/// Applies only if PageDestinationType is FitR.
/// </summary>
public double Right // Cannot be null in a valid PDF.
{
get { return _right; }
set { _right = value; }
}
double _right = double.NaN;
/// <summary>
/// Gets or sets the bottom position of the page positioned at the bottom side of the window.
/// Applies only if PageDestinationType is FitR.
/// </summary>
public double Bottom // Cannot be null in a valid PDF.
{
get { return _bottom; }
set { _bottom = value; }
}
double _bottom = double.NaN;
/// <summary>
/// Gets or sets the zoom faction of the page.
/// Applies only if PageDestinationType is Xyz.
/// </summary>
public double? Zoom
{
get { return _zoom; }
set
{
if (value.HasValue && value.Value == 0)
_zoom = null;
else
_zoom = value;
}
}
double? _zoom; // PDF treats 0 and null equally.
/// <summary>
/// Gets or sets whether the outline item is opened (or expanded).
/// </summary>
public bool Opened
{
get { return _opened; }
#if true
set { _opened = value; }
#else
// TODO: adjust openCount of ascendant...
set
{
if (_opened != value)
{
_opened = value;
int sign = value ? 1 : -1;
PdfOutline parent = _parent;
if (_opened)
{
while (parent != null)
parent.openCount += 1 + _openCount;
}
else
{
}
}
}
#endif
}
bool _opened;
/// <summary>
/// Gets or sets the style of the outline text.
/// </summary>
public PdfOutlineStyle Style
{
get { return (PdfOutlineStyle)Elements.GetInteger(Keys.F); }
set { Elements.SetInteger(Keys.F, (int)value); }
}
/// <summary>
/// Gets or sets the type of the page destination.
/// </summary>
public PdfPageDestinationType PageDestinationType
{
get { return _pageDestinationType; }
set { _pageDestinationType = value; }
}
PdfPageDestinationType _pageDestinationType = PdfPageDestinationType.Xyz;
/// <summary>
/// Gets or sets the color of the text.
/// </summary>
/// <value>The color of the text.</value>
public XColor TextColor
{
get { return _textColor; }
set { _textColor = value; }
}
XColor _textColor;
/// <summary>
/// Gets a value indicating whether this outline object has child items.
/// </summary>
public bool HasChildren
{
get { return _outlines != null && _outlines.Count > 0; }
}
/// <summary>
/// Gets the outline collection of this node.
/// </summary>
public PdfOutlineCollection Outlines
{
get { return _outlines ?? (_outlines = new PdfOutlineCollection(Owner, this)); }
}
PdfOutlineCollection _outlines;
/// <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();
}
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
}
void InitializeChildren()
{
PdfReference firstRef = Elements.GetReference(Keys.First);
PdfReference lastRef = Elements.GetReference(Keys.Last);
PdfReference current = firstRef;
while (current != null)
{
// Create item and add it to outline items dictionary.
PdfOutline item = new PdfOutline((PdfDictionary)current.Value);
Outlines.Add(item);
current = item.Elements.GetReference(Keys.Next);
#if DEBUG_
if (current == null)
{
if (item.Reference != lastRef)
{
// Word produces PDFs that come to this case.
GetType();
}
}
#endif
}
}
/// <summary>
/// Creates key/values pairs according to the object structure.
/// </summary>
internal override void PrepareForSave()
{
bool hasKids = HasChildren;
// Is something to do at all?
if (_parent != null || hasKids)
{
if (_parent == null)
{
// Case: This is the outline dictionary (the root).
// Reference: TABLE 8.3 Entries in the outline dictionary / Page 585
Debug.Assert(_outlines != null && _outlines.Count > 0 && _outlines[0] != null);
Elements[Keys.First] = _outlines[0].Reference;
Elements[Keys.Last] = _outlines[_outlines.Count - 1].Reference;
// TODO: /Count - the meaning is not completely clear to me.
// Get PDFs created with Acrobat and analyze what to implement.
if (OpenCount > 0)
Elements[Keys.Count] = new PdfInteger(OpenCount);
}
else
{
// Case: This is an outline item dictionary.
// Reference: TABLE 8.4 Entries in the outline item dictionary / Page 585
Elements[Keys.Parent] = _parent.Reference;
int count = _parent._outlines.Count;
int index = _parent._outlines.IndexOf(this);
Debug.Assert(index != -1);
// Has destination?
if (DestinationPage != null)
Elements[Keys.Dest] = CreateDestArray();
// Not the first element?
if (index > 0)
Elements[Keys.Prev] = _parent._outlines[index - 1].Reference;
// Not the last element?
if (index < count - 1)
Elements[Keys.Next] = _parent._outlines[index + 1].Reference;
if (hasKids)
{
Elements[Keys.First] = _outlines[0].Reference;
Elements[Keys.Last] = _outlines[_outlines.Count - 1].Reference;
}
// TODO: /Count - the meaning is not completely clear to me
if (OpenCount > 0)
Elements[Keys.Count] = new PdfInteger((_opened ? 1 : -1) * OpenCount);
if (_textColor != XColor.Empty && Owner.HasVersion("1.4"))
Elements[Keys.C] = new PdfLiteral("[{0}]", PdfEncoders.ToString(_textColor, PdfColorMode.Rgb));
// if (Style != PdfOutlineStyle.Regular && Document.HasVersion("1.4"))
// //pdf.AppendFormat("/F {0}\n", (int)_style);
// Elements[Keys.F] = new PdfInteger((int)_style);
}
// Prepare child elements.
if (hasKids)
{
foreach (PdfOutline outline in _outlines)
outline.PrepareForSave();
}
}
}
PdfArray CreateDestArray()
{
PdfArray dest = null;
switch (PageDestinationType)
{
// [page /XYZ left top zoom]
case PdfPageDestinationType.Xyz:
dest = new PdfArray(Owner,
DestinationPage.Reference, new PdfLiteral(String.Format("/XYZ {0} {1} {2}", Fd(Left), Fd(Top), Fd(Zoom))));
break;
// [page /Fit]
case PdfPageDestinationType.Fit:
dest = new PdfArray(Owner,
DestinationPage.Reference, new PdfLiteral("/Fit"));
break;
// [page /FitH top]
case PdfPageDestinationType.FitH:
dest = new PdfArray(Owner,
DestinationPage.Reference, new PdfLiteral(String.Format("/FitH {0}", Fd(Top))));
break;
// [page /FitV left]
case PdfPageDestinationType.FitV:
dest = new PdfArray(Owner,
DestinationPage.Reference, new PdfLiteral(String.Format("/FitV {0}", Fd(Left))));
break;
// [page /FitR left bottom right top]
case PdfPageDestinationType.FitR:
dest = new PdfArray(Owner,
DestinationPage.Reference, new PdfLiteral(String.Format("/FitR {0} {1} {2} {3}", Fd(Left), Fd(Bottom), Fd(Right), Fd(Top))));
break;
// [page /FitB]
case PdfPageDestinationType.FitB:
dest = new PdfArray(Owner,
DestinationPage.Reference, new PdfLiteral("/FitB"));
break;
// [page /FitBH top]
case PdfPageDestinationType.FitBH:
dest = new PdfArray(Owner,
DestinationPage.Reference, new PdfLiteral(String.Format("/FitBH {0}", Fd(Top))));
break;
// [page /FitBV left]
case PdfPageDestinationType.FitBV:
dest = new PdfArray(Owner,
DestinationPage.Reference, new PdfLiteral(String.Format("/FitBV {0}", Fd(Left))));
break;
default:
throw new ArgumentOutOfRangeException();
}
return dest;
}
/// <summary>
/// Format double.
/// </summary>
string Fd(double value)
{
if (Double.IsNaN(value))
throw new InvalidOperationException("Value is not a valid Double.");
return value.ToString("#.##", CultureInfo.InvariantCulture);
//return Double.IsNaN(value) ? "null" : value.ToString("#.##", CultureInfo.InvariantCulture);
}
/// <summary>
/// Format nullable double.
/// </summary>
string Fd(double? value)
{
return value.HasValue ? value.Value.ToString("#.##", CultureInfo.InvariantCulture) : "null";
}
internal override void WriteObject(PdfWriter writer)
{
#if DEBUG
writer.WriteRaw("% Title = " + FilterUnicode(Title) + "\n");
#endif
// TODO: Proof that there is nothing to do here.
bool hasKids = HasChildren;
if (_parent != null || hasKids)
{
////// Everything done in PrepareForSave
////if (_parent == null)
////{
//// // This is the outline dictionary (the root)
////}
////else
////{
//// // This is an outline item dictionary
////}
base.WriteObject(writer);
}
}
#if DEBUG
private string FilterUnicode(string text)
{
StringBuilder result = new StringBuilder();
foreach (char ch in text)
result.Append((uint)ch < 256 ? (ch != '\r' && ch != '\n' ? ch : ' ') : '?');
return result.ToString();
}
#endif
/// <summary>
/// Predefined keys of this dictionary.
/// </summary>
internal sealed class Keys : KeysBase
{
// ReSharper disable InconsistentNaming
/// <summary>
/// (Optional) The type of PDF object that this dictionary describes; if present,
/// must be Outlines for an outline dictionary.
/// </summary>
[KeyInfo(KeyType.Name | KeyType.Optional, FixedValue = "Outlines")]
public const string Type = "/Type";
// Outline and outline item are combined
///// <summary>
///// (Required if there are any open or closed outline entries; must be an indirect reference)
///// An outline item dictionary representing the first top-level item in the outline.
///// </summary>
//[KeyInfo(KeyType.Dictionary)]
//public const string First = "/First";
//
///// <summary>
///// (Required if there are any open or closed outline entries; must be an indirect reference)
///// An outline item dictionary representing the last top-level item in the outline.
///// </summary>
//[KeyInfo(KeyType.Dictionary)]
//public const string Last = "/Last";
//
///// <summary>
///// (Required if the document has any open outline entries) The total number of open items at all
///// levels of the outline. This entry should be omitted if there are no open outline items.
///// </summary>
//[KeyInfo(KeyType.Integer)]
//public const string Count = "/Count";
/// <summary>
/// (Required) The text to be displayed on the screen for this item.
/// </summary>
[KeyInfo(KeyType.String | KeyType.Required)]
public const string Title = "/Title";
/// <summary>
/// (Required; must be an indirect reference) The parent of this item in the outline hierarchy.
/// The parent of a top-level item is the outline dictionary itself.
/// </summary>
[KeyInfo(KeyType.Dictionary | KeyType.Required)]
public const string Parent = "/Parent";
/// <summary>
/// (Required for all but the first item at each level; must be an indirect reference)
/// The previous item at this outline level.
/// </summary>
[KeyInfo(KeyType.Dictionary | KeyType.Required)]
public const string Prev = "/Prev";
/// <summary>
/// (Required for all but the last item at each level; must be an indirect reference)
/// The next item at this outline level.
/// </summary>
[KeyInfo(KeyType.Dictionary | KeyType.Required)]
public const string Next = "/Next";
/// <summary>
/// (Required if the item has any descendants; must be an indirect reference)
/// The first of this item<65>s immediate children in the outline hierarchy.
/// </summary>
[KeyInfo(KeyType.Dictionary | KeyType.Required)]
public const string First = "/First";
/// <summary>
/// (Required if the item has any descendants; must be an indirect reference)
/// The last of this item<65>s immediate children in the outline hierarchy.
/// </summary>
[KeyInfo(KeyType.Dictionary | KeyType.Required)]
public const string Last = "/Last";
/// <summary>
/// (Required if the item has any descendants) If the item is open, the total number of its
/// open descendants at all lower levels of the outline hierarchy. If the item is closed, a
/// negative integer whose absolute value specifies how many descendants would appear if the
/// item were reopened.
/// </summary>
[KeyInfo(KeyType.Integer | KeyType.Required)]
public const string Count = "/Count";
/// <summary>
/// (Optional; not permitted if an A entry is present) The destination to be displayed when this
/// item is activated.
/// </summary>
[KeyInfo(KeyType.ArrayOrNameOrString | KeyType.Optional)]
public const string Dest = "/Dest";
/// <summary>
/// (Optional; not permitted if a Dest entry is present) The action to be performed when
/// this item is activated.
/// </summary>
[KeyInfo(KeyType.Dictionary | KeyType.Optional)]
public const string A = "/A";
/// <summary>
/// (Optional; PDF 1.3; must be an indirect reference) The structure element to which the item
/// refers.
/// Note: The ability to associate an outline item with a structure element (such as the beginning
/// of a chapter) is a PDF 1.3 feature. For backward compatibility with earlier PDF versions, such
/// an item should also specify a destination (Dest) corresponding to an area of a page where the
/// contents of the designated structure element are displayed.
/// </summary>
[KeyInfo(KeyType.Dictionary | KeyType.Optional)]
public const string SE = "/SE";
/// <summary>
/// (Optional; PDF 1.4) An array of three numbers in the range 0.0 to 1.0, representing the
/// components in the DeviceRGB color space of the color to be used for the outline entry<72>s text.
/// Default value: [0.0 0.0 0.0].
/// </summary>
[KeyInfo(KeyType.Array | KeyType.Optional)]
public const string C = "/C";
/// <summary>
/// (Optional; PDF 1.4) A set of flags specifying style characteristics for displaying the outline
/// item<65>s text. Default value: 0.
/// </summary>
[KeyInfo(KeyType.Integer | KeyType.Optional)]
public const string F = "/F";
/// <summary>
/// Gets the KeysMeta for these keys.
/// </summary>
public static DictionaryMeta Meta
{
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
}
static DictionaryMeta _meta;
// ReSharper restore InconsistentNaming
}
/// <summary>
/// Gets the KeysMeta of this dictionary type.
/// </summary>
internal override DictionaryMeta Meta
{
get { return Keys.Meta; }
}
}
}

View File

@@ -0,0 +1,338 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Collections;
using PdfSharp.Drawing;
// Review: CountOpen does not work. - StL/14-10-05
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a collection of outlines.
/// </summary>
public class PdfOutlineCollection : PdfObject, ICollection<PdfOutline>, IList<PdfOutline>
{
/// <summary>
/// Can only be created as part of PdfOutline.
/// </summary>
internal PdfOutlineCollection(PdfDocument document, PdfOutline parent)
: base(document)
{
_parent = parent;
}
/// <summary>
/// Indicates whether the outline collection has at least one entry.
/// </summary>
[Obsolete("Use 'Count > 0' - HasOutline will throw exception.")]
public bool HasOutline // DELETE: 15-10-01
{
get
{
//return Count > 0;
throw new InvalidOperationException("Use 'Count > 0'");
}
}
/// <summary>
/// Removes the first occurrence of a specific item from the collection.
/// </summary>
public bool Remove(PdfOutline item)
{
if (_outlines.Remove(item))
{
RemoveFromOutlinesTree(item);
return true;
}
return false;
}
/// <summary>
/// Gets the number of entries in this collection.
/// </summary>
public int Count
{
get { return _outlines.Count; }
}
/// <summary>
/// Returns false.
/// </summary>
public bool IsReadOnly
{
get { return false; }
}
/// <summary>
/// Adds the specified outline.
/// </summary>
public void Add(PdfOutline outline)
{
if (outline == null)
throw new ArgumentNullException("outline");
// DestinationPage is optional. PDFsharp does not yet support outlines with action ("/A") instead of destination page ("/DEST")
if (outline.DestinationPage != null && !ReferenceEquals(Owner, outline.DestinationPage.Owner))
throw new ArgumentException("Destination page must belong to this document.");
//// TODO check the parent problems...
////outline.Document = Owner;
////outline.Parent = _parent;
////Owner._irefTable.Add(outline);
AddToOutlinesTree(outline);
_outlines.Add(outline);
if (outline.Opened)
{
outline = _parent;
while (outline != null)
{
outline.OpenCount++;
outline = outline.Parent;
}
}
}
/// <summary>
/// Removes all elements form the collection.
/// </summary>
public void Clear()
{
if (Count > 0)
{
PdfOutline[] array = new PdfOutline[Count];
_outlines.CopyTo(array);
_outlines.Clear();
foreach (PdfOutline item in array)
{
RemoveFromOutlinesTree(item);
}
}
}
/// <summary>
/// Determines whether the specified element is in the collection.
/// </summary>
public bool Contains(PdfOutline item)
{
return _outlines.Contains(item);
}
/// <summary>
/// Copies the collection to an array, starting at the specified index of the target array.
/// </summary>
public void CopyTo(PdfOutline[] array, int arrayIndex)
{
_outlines.CopyTo(array, arrayIndex);
}
/// <summary>
/// Adds the specified outline entry.
/// </summary>
/// <param name="title">The outline text.</param>
/// <param name="destinationPage">The destination page.</param>
/// <param name="opened">Specifies whether the node is displayed expanded (opened) or collapsed.</param>
/// <param name="style">The font style used to draw the outline text.</param>
/// <param name="textColor">The color used to draw the outline text.</param>
public PdfOutline Add(string title, PdfPage destinationPage, bool opened, PdfOutlineStyle style, XColor textColor)
{
PdfOutline outline = new PdfOutline(title, destinationPage, opened, style, textColor);
Add(outline);
return outline;
}
/// <summary>
/// Adds the specified outline entry.
/// </summary>
/// <param name="title">The outline text.</param>
/// <param name="destinationPage">The destination page.</param>
/// <param name="opened">Specifies whether the node is displayed expanded (opened) or collapsed.</param>
/// <param name="style">The font style used to draw the outline text.</param>
public PdfOutline Add(string title, PdfPage destinationPage, bool opened, PdfOutlineStyle style)
{
PdfOutline outline = new PdfOutline(title, destinationPage, opened, style);
Add(outline);
return outline;
}
/// <summary>
/// Adds the specified outline entry.
/// </summary>
/// <param name="title">The outline text.</param>
/// <param name="destinationPage">The destination page.</param>
/// <param name="opened">Specifies whether the node is displayed expanded (opened) or collapsed.</param>
public PdfOutline Add(string title, PdfPage destinationPage, bool opened)
{
PdfOutline outline = new PdfOutline(title, destinationPage, opened);
Add(outline);
return outline;
}
/// <summary>
/// Creates a PdfOutline and adds it into the outline collection.
/// </summary>
public PdfOutline Add(string title, PdfPage destinationPage)
{
PdfOutline outline = new PdfOutline(title, destinationPage);
Add(outline);
return outline;
}
/// <summary>
/// Gets the index of the specified item.
/// </summary>
public int IndexOf(PdfOutline item)
{
return _outlines.IndexOf(item);
}
/// <summary>
/// Inserts the item at the specified index.
/// </summary>
public void Insert(int index, PdfOutline outline)
{
if (outline == null)
throw new ArgumentNullException("outline");
if (index < 0 || index >= _outlines.Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.OutlineIndexOutOfRange);
AddToOutlinesTree(outline);
_outlines.Insert(index, outline);
}
/// <summary>
/// Removes the outline item at the specified index.
/// </summary>
public void RemoveAt(int index)
{
PdfOutline outline = _outlines[index];
_outlines.RemoveAt(index);
RemoveFromOutlinesTree(outline);
}
/// <summary>
/// Gets the <see cref="PdfSharp.Pdf.PdfOutline"/> at the specified index.
/// </summary>
public PdfOutline this[int index]
{
get
{
if (index < 0 || index >= _outlines.Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.OutlineIndexOutOfRange);
return _outlines[index];
}
set
{
if (index < 0 || index >= _outlines.Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.OutlineIndexOutOfRange);
if (value == null)
throw new ArgumentOutOfRangeException("value", null, PSSR.SetValueMustNotBeNull);
AddToOutlinesTree(value);
_outlines[index] = value;
}
}
/// <summary>
/// Returns an enumerator that iterates through the outline collection.
/// </summary>
public IEnumerator<PdfOutline> GetEnumerator()
{
return _outlines.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
internal int CountOpen()
{
int count = 0;
//foreach (PdfOutline outline in _outlines)
// count += outline.CountOpen();
return count;
}
void AddToOutlinesTree(PdfOutline outline)
{
if (outline == null)
throw new ArgumentNullException("outline");
// DestinationPage is optional. PDFsharp does not yet support outlines with action ("/A") instead of destination page ("/DEST")
if (outline.DestinationPage != null && !ReferenceEquals(Owner, outline.DestinationPage.Owner))
throw new ArgumentException("Destination page must belong to this document.");
// TODO check the parent problems...
outline.Document = Owner;
outline.Parent = _parent;
//_outlines.Add(outline);
if (!Owner._irefTable.Contains(outline.ObjectID))
Owner._irefTable.Add(outline);
else
{
outline.GetType();
}
//if (outline.Opened)
//{
// outline = _parent;
// while (outline != null)
// {
// outline.OpenCount++;
// outline = outline.Parent;
// }
//}
}
void RemoveFromOutlinesTree(PdfOutline outline)
{
if (outline == null)
throw new ArgumentNullException("outline");
// TODO check the parent problems...
//outline.Document = Owner;
outline.Parent = null;
Owner._irefTable.Remove(outline.Reference);
}
/// <summary>
/// The parent outine of this collection.
/// </summary>
readonly PdfOutline _parent;
readonly List<PdfOutline> _outlines = new List<PdfOutline>();
}
}

1028
PdfSharp/Pdf/PdfPage.cs Normal file

File diff suppressed because it is too large Load Diff

749
PdfSharp/Pdf/PdfPages.cs Normal file
View File

@@ -0,0 +1,749 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Collections;
using PdfSharp.Pdf.IO;
using PdfSharp.Pdf.Advanced;
using PdfSharp.Pdf.Annotations;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents the pages of the document.
/// </summary>
[DebuggerDisplay("(PageCount={Count})")]
public sealed class PdfPages : PdfDictionary, IEnumerable<PdfPage>
{
internal PdfPages(PdfDocument document)
: base(document)
{
Elements.SetName(Keys.Type, "/Pages");
Elements[Keys.Count] = new PdfInteger(0);
}
internal PdfPages(PdfDictionary dictionary)
: base(dictionary)
{ }
/// <summary>
/// Gets the number of pages.
/// </summary>
public int Count
{
get { return PagesArray.Elements.Count; }
}
/// <summary>
/// Gets the page with the specified index.
/// </summary>
public PdfPage this[int index]
{
get
{
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException("index", index, PSSR.PageIndexOutOfRange);
PdfDictionary dict = (PdfDictionary)((PdfReference)PagesArray.Elements[index]).Value;
if (!(dict is PdfPage))
dict = new PdfPage(dict);
return (PdfPage)dict;
}
}
/// <summary>
/// Finds a page by its id. Transforms it to PdfPage if necessary.
/// </summary>
internal PdfPage FindPage(PdfObjectID id) // TODO: public?
{
PdfPage page = null;
foreach (PdfItem item in PagesArray)
{
PdfReference reference = item as PdfReference;
if (reference != null)
{
PdfDictionary dictionary = reference.Value as PdfDictionary;
if (dictionary != null && dictionary.ObjectID == id)
{
page = dictionary as PdfPage ?? new PdfPage(dictionary);
break;
}
}
}
return page;
}
/// <summary>
/// Creates a new PdfPage, adds it to the end of this document, and returns it.
/// </summary>
public PdfPage Add()
{
PdfPage page = new PdfPage();
Insert(Count, page);
return page;
}
/// <summary>
/// Adds the specified PdfPage to the end of this document and maybe returns a new PdfPage object.
/// The value returned is a new object if the added page comes from a foreign document.
/// </summary>
public PdfPage Add(PdfPage page)
{
return Insert(Count, page);
}
/// <summary>
/// Creates a new PdfPage, inserts it at the specified position into this document, and returns it.
/// </summary>
public PdfPage Insert(int index)
{
PdfPage page = new PdfPage();
Insert(index, page);
return page;
}
/// <summary>
/// Inserts the specified PdfPage at the specified position to this document and maybe returns a new PdfPage object.
/// The value returned is a new object if the inserted page comes from a foreign document.
/// </summary>
public PdfPage Insert(int index, PdfPage page)
{
if (page == null)
throw new ArgumentNullException("page");
// Is the page already owned by this document?
if (page.Owner == Owner)
{
// Case: Page is first removed and than inserted again, maybe at another position.
int count = Count;
// Check if page is not already part of the document.
for (int idx = 0; idx < count; idx++)
{
if (ReferenceEquals(this[idx], page))
throw new InvalidOperationException(PSSR.MultiplePageInsert);
}
// TODO: check this case
// Because the owner of the inserted page is this document we assume that the page was former part of it
// and it is therefore well-defined.
Owner._irefTable.Add(page);
Debug.Assert(page.Owner == Owner);
// Insert page in array.
PagesArray.Elements.Insert(index, page.Reference);
// Update page count.
Elements.SetInteger(Keys.Count, PagesArray.Elements.Count);
return page;
}
// All new page insertions come here.
if (page.Owner == null)
{
// Case: New page was newly created and inserted now.
page.Document = Owner;
Owner._irefTable.Add(page);
Debug.Assert(page.Owner == Owner);
PagesArray.Elements.Insert(index, page.Reference);
Elements.SetInteger(Keys.Count, PagesArray.Elements.Count);
}
else
{
// Case: Page is from an external document -> import it.
PdfPage importPage = page;
page = ImportExternalPage(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(index, page.Reference);
Elements.SetInteger(Keys.Count, PagesArray.Elements.Count);
PdfAnnotations.FixImportedAnnotation(page);
}
if (Owner.Settings.TrimMargins.AreSet)
page.TrimMargins = Owner.Settings.TrimMargins;
return page;
}
/// <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.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.Add(PdfPage.Keys.Annots, annotations);
}
}
}
}
/// <summary>
/// Inserts all 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>
public void InsertRange(int index, PdfDocument document)
{
if (document == null)
throw new ArgumentNullException("document");
InsertRange(index, document, 0, document.PageCount);
}
/// <summary>
/// Inserts all 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>
public void InsertRange(int index, PdfDocument document, int startIndex)
{
if (document == null)
throw new ArgumentNullException("document");
InsertRange(index, document, startIndex, document.PageCount - startIndex);
}
/// <summary>
/// Removes the specified page from the document.
/// </summary>
public void Remove(PdfPage page)
{
PagesArray.Elements.Remove(page.Reference);
Elements.SetInteger(Keys.Count, PagesArray.Elements.Count);
}
/// <summary>
/// Removes the specified page from the document.
/// </summary>
public void RemoveAt(int index)
{
PagesArray.Elements.RemoveAt(index);
Elements.SetInteger(Keys.Count, PagesArray.Elements.Count);
}
/// <summary>
/// Moves a page within the page sequence.
/// </summary>
/// <param name="oldIndex">The page index before this operation.</param>
/// <param name="newIndex">The page index after this operation.</param>
public void MovePage(int oldIndex, int newIndex)
{
if (oldIndex < 0 || oldIndex >= Count)
throw new ArgumentOutOfRangeException("oldIndex");
if (newIndex < 0 || newIndex >= Count)
throw new ArgumentOutOfRangeException("newIndex");
if (oldIndex == newIndex)
return;
//PdfPage page = (PdfPage)pagesArray.Elements[oldIndex];
PdfReference page = (PdfReference)_pagesArray.Elements[oldIndex];
_pagesArray.Elements.RemoveAt(oldIndex);
_pagesArray.Elements.Insert(newIndex, page);
}
/// <summary>
/// Imports an external page. The elements of the imported page are cloned and added to this document.
/// Important: In contrast to PdfFormXObject adding an external page always make a deep copy
/// of their transitive closure. Any reuse of already imported objects is not intended because
/// any modification of an imported page must not change another page.
/// </summary>
PdfPage ImportExternalPage(PdfPage importPage)
{
if (importPage.Owner._openMode != PdfDocumentOpenMode.Import)
throw new InvalidOperationException("A PDF document must be opened with PdfDocumentOpenMode.Import to import pages from it.");
PdfPage page = new PdfPage(_document);
// ReSharper disable AccessToStaticMemberViaDerivedType for a better code readability.
CloneElement(page, importPage, PdfPage.Keys.Resources, false);
CloneElement(page, importPage, PdfPage.Keys.Contents, false);
CloneElement(page, importPage, PdfPage.Keys.MediaBox, true);
CloneElement(page, importPage, PdfPage.Keys.CropBox, true);
CloneElement(page, importPage, PdfPage.Keys.Rotate, true);
CloneElement(page, importPage, PdfPage.Keys.BleedBox, true);
CloneElement(page, importPage, PdfPage.Keys.TrimBox, true);
CloneElement(page, importPage, PdfPage.Keys.ArtBox, true);
#if true
// Do not deep copy annotations.
CloneElement(page, importPage, PdfPage.Keys.Annots, false);
#else
// Deep copy annotations.
CloneElement(page, importPage, PdfPage.Keys.Annots, true);
#endif
// ReSharper restore AccessToStaticMemberViaDerivedType
// TODO more elements?
return page;
}
/// <summary>
/// Helper function for ImportExternalPage.
/// </summary>
void CloneElement(PdfPage page, PdfPage importPage, string key, bool deepcopy)
{
Debug.Assert(page != null);
Debug.Assert(page.Owner == _document);
Debug.Assert(importPage.Owner != null);
Debug.Assert(importPage.Owner != _document);
PdfItem item = importPage.Elements[key];
if (item != null)
{
PdfImportedObjectTable importedObjectTable = null;
if (!deepcopy)
importedObjectTable = Owner.FormTable.GetImportedObjectTable(importPage);
// The item can be indirect. If so, replace it by its value.
if (item is PdfReference)
item = ((PdfReference)item).Value;
if (item is PdfObject)
{
PdfObject root = (PdfObject)item;
if (deepcopy)
{
Debug.Assert(root.Owner != null, "See 'else' case for details");
root = DeepCopyClosure(_document, root);
}
else
{
// The owner can be null if the item is not a reference.
if (root.Owner == null)
root.Document = importPage.Owner;
root = ImportClosure(importedObjectTable, page.Owner, root);
}
if (root.Reference == null)
page.Elements[key] = root;
else
page.Elements[key] = root.Reference;
}
else
{
// Simple items are just cloned.
page.Elements[key] = item.Clone();
}
}
}
static PdfReference RemapReference(PdfPage[] newPages, PdfPage[] impPages, PdfReference iref)
{
// Directs the iref to a one of the imported pages?
for (int idx = 0; idx < newPages.Length; idx++)
{
if (impPages[idx].Reference == iref)
return newPages[idx].Reference;
}
return null;
}
/// <summary>
/// Gets a PdfArray containing all pages of this document. The array must not be modified.
/// </summary>
public PdfArray PagesArray
{
get
{
if (_pagesArray == null)
_pagesArray = (PdfArray)Elements.GetValue(Keys.Kids, VCF.Create);
return _pagesArray;
}
}
PdfArray _pagesArray;
/// <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);
}
/// <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)
{
PdfReference xref3 = kid.Elements["/Kids"] as PdfReference;
if (xref3 != null)
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();
}
/// <summary>
/// Prepares the document for saving.
/// </summary>
internal override void PrepareForSave()
{
// TODO: Close all open content streams
// TODO: Create the page tree.
// Arrays have a limit of 8192 entries, but I successfully tested documents
// with 50000 pages and no page tree.
// ==> wait for bug report.
int count = _pagesArray.Elements.Count;
for (int idx = 0; idx < count; idx++)
{
PdfPage page = this[idx];
page.PrepareForSave();
}
}
/// <summary>
/// Gets the enumerator.
/// </summary>
public new IEnumerator<PdfPage> GetEnumerator()
{
return new PdfPagesEnumerator(this);
}
class PdfPagesEnumerator : IEnumerator<PdfPage>
{
internal PdfPagesEnumerator(PdfPages list)
{
_list = list;
_index = -1;
}
public bool MoveNext()
{
if (_index < _list.Count - 1)
{
_index++;
_currentElement = _list[_index];
return true;
}
_index = _list.Count;
return false;
}
public void Reset()
{
_currentElement = null;
_index = -1;
}
object IEnumerator.Current
{
get { return Current; }
}
public PdfPage Current
{
get
{
if (_index == -1 || _index >= _list.Count)
throw new InvalidOperationException(PSSR.ListEnumCurrentOutOfRange);
return _currentElement;
}
}
public void Dispose()
{
// Nothing to do.
}
PdfPage _currentElement;
int _index;
readonly PdfPages _list;
}
/// <summary>
/// Predefined keys of this dictionary.
/// </summary>
internal sealed class Keys : PdfPage.InheritablePageKeys
{
/// <summary>
/// (Required) The type of PDF object that this dictionary describes;
/// must be Pages for a page tree node.
/// </summary>
[KeyInfo(KeyType.Name | KeyType.Required, FixedValue = "Pages")]
public const string Type = "/Type";
/// <summary>
/// (Required except in root node; must be an indirect reference)
/// The page tree node that is the immediate parent of this one.
/// </summary>
[KeyInfo(KeyType.Dictionary | KeyType.Required)]
public const string Parent = "/Parent";
/// <summary>
/// (Required) An array of indirect references to the immediate children of this node.
/// The children may be page objects or other page tree nodes.
/// </summary>
[KeyInfo(KeyType.Array | KeyType.Required)]
public const string Kids = "/Kids";
/// <summary>
/// (Required) The number of leaf nodes (page objects) that are descendants of this node
/// within the page tree.
/// </summary>
[KeyInfo(KeyType.Integer | KeyType.Required)]
public const string Count = "/Count";
/// <summary>
/// Gets the KeysMeta for these keys.
/// </summary>
public static DictionaryMeta Meta
{
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
}
static DictionaryMeta _meta;
}
/// <summary>
/// Gets the KeysMeta of this dictionary type.
/// </summary>
internal override DictionaryMeta Meta
{
get { return Keys.Meta; }
}
}
}

83
PdfSharp/Pdf/PdfReal.cs Normal file
View File

@@ -0,0 +1,83 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System.Diagnostics;
using System.Globalization;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a direct real value.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfReal : PdfNumber
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfReal"/> class.
/// </summary>
public PdfReal()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfReal"/> class.
/// </summary>
/// <param name="value">The value.</param>
public PdfReal(double value)
{
_value = value;
}
/// <summary>
/// Gets the value as double.
/// </summary>
public double Value
{
// This class must behave like a value type. Therefore it cannot be changed (like System.String).
get { return _value; }
}
readonly double _value;
/// <summary>
/// Returns the real number as string.
/// </summary>
public override string ToString()
{
return _value.ToString(Config.SignificantFigures3, CultureInfo.InvariantCulture);
}
/// <summary>
/// Writes the real value with up to three digits.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.Write(this);
}
}
}

View File

@@ -0,0 +1,95 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System.Globalization;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents an indirect real value. This type is not used by PDFsharp. If it is imported from
/// an external PDF file, the value is converted into a direct object.
/// </summary>
public sealed class PdfRealObject : PdfNumberObject
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfRealObject"/> class.
/// </summary>
public PdfRealObject()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfRealObject"/> class.
/// </summary>
/// <param name="value">The value.</param>
public PdfRealObject(double value)
{
_value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfRealObject"/> class.
/// </summary>
/// <param name="document">The document.</param>
/// <param name="value">The value.</param>
public PdfRealObject(PdfDocument document, double value)
: base(document)
{
_value = value;
}
/// <summary>
/// Gets or sets the value.
/// </summary>
public double Value
{
get { return _value; }
set { _value = value; }
}
double _value;
/// <summary>
/// Returns the real as a culture invariant string.
/// </summary>
public override string ToString()
{
return _value.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Writes the real literal.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.WriteBeginObject(this);
writer.Write(_value);
writer.WriteEndObject();
}
}
}

View File

@@ -0,0 +1,499 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using System.Globalization;
#if GDI
using System.Drawing;
#endif
#if WPF
using System.Windows.Media;
#endif
using PdfSharp.Drawing;
using PdfSharp.Pdf.Advanced;
using PdfSharp.Pdf.IO;
using PdfSharp.Pdf.Internal;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a PDF rectangle value, that is internally an array with 4 real values.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay}")]
public sealed class PdfRectangle : PdfItem
{
// This class must behave like a value type. Therefore it cannot be changed (like System.String).
/// <summary>
/// Initializes a new instance of the PdfRectangle class.
/// </summary>
public PdfRectangle()
{ }
/// <summary>
/// Initializes a new instance of the PdfRectangle class with two points specifying
/// two diagonally opposite corners. Notice that in contrast to GDI+ convention the
/// 3rd and the 4th parameter specify a point and not a width. This is so much confusing
/// that this function is for internal use only.
/// </summary>
internal PdfRectangle(double x1, double y1, double x2, double y2)
{
_x1 = x1;
_y1 = y1;
_x2 = x2;
_y2 = y2;
}
#if GDI
/// <summary>
/// Initializes a new instance of the PdfRectangle class with two points specifying
/// two diagonally opposite corners.
/// </summary>
public PdfRectangle(PointF pt1, PointF pt2)
{
_x1 = pt1.X;
_y1 = pt1.Y;
_x2 = pt2.X;
_y2 = pt2.Y;
}
#endif
/// <summary>
/// Initializes a new instance of the PdfRectangle class with two points specifying
/// two diagonally opposite corners.
/// </summary>
public PdfRectangle(XPoint pt1, XPoint pt2)
{
_x1 = pt1.X;
_y1 = pt1.Y;
_x2 = pt2.X;
_y2 = pt2.Y;
}
#if GDI
/// <summary>
/// Initializes a new instance of the PdfRectangle class with the specified location and size.
/// </summary>
public PdfRectangle(PointF pt, SizeF size)
{
_x1 = pt.X;
_y1 = pt.Y;
_x2 = pt.X + size.Width;
_y2 = pt.Y + size.Height;
}
#endif
/// <summary>
/// Initializes a new instance of the PdfRectangle class with the specified location and size.
/// </summary>
public PdfRectangle(XPoint pt, XSize size)
{
_x1 = pt.X;
_y1 = pt.Y;
_x2 = pt.X + size.Width;
_y2 = pt.Y + size.Height;
}
/// <summary>
/// Initializes a new instance of the PdfRectangle class with the specified XRect.
/// </summary>
public PdfRectangle(XRect rect)
{
_x1 = rect.X;
_y1 = rect.Y;
_x2 = rect.X + rect.Width;
_y2 = rect.Y + rect.Height;
}
/// <summary>
/// Initializes a new instance of the PdfRectangle class with the specified PdfArray.
/// </summary>
internal PdfRectangle(PdfItem item)
{
if (item == null || item is PdfNull)
return;
if (item is PdfReference)
item = ((PdfReference)item).Value;
PdfArray array = item as PdfArray;
if (array == null)
throw new InvalidOperationException(PSSR.UnexpectedTokenInPdfFile);
_x1 = array.Elements.GetReal(0);
_y1 = array.Elements.GetReal(1);
_x2 = array.Elements.GetReal(2);
_y2 = array.Elements.GetReal(3);
}
/// <summary>
/// Clones this instance.
/// </summary>
public new PdfRectangle Clone()
{
return (PdfRectangle)Copy();
}
/// <summary>
/// Implements cloning this instance.
/// </summary>
protected override object Copy()
{
PdfRectangle rect = (PdfRectangle)base.Copy();
return rect;
}
/// <summary>
/// Tests whether all coordinate are zero.
/// </summary>
public bool IsEmpty
{
// ReSharper disable CompareOfFloatsByEqualityOperator
get { return _x1 == 0 && _y1 == 0 && _x2 == 0 && _y2 == 0; }
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Tests whether the specified object is a PdfRectangle and has equal coordinates.
/// </summary>
public override bool Equals(object obj)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
PdfRectangle rectangle = obj as PdfRectangle;
if (rectangle != null)
{
PdfRectangle rect = rectangle;
return rect._x1 == _x1 && rect._y1 == _y1 && rect._x2 == _x2 && rect._y2 == _y2;
}
return false;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Serves as a hash function for a particular type.
/// </summary>
public override int GetHashCode()
{
// This code is from System.Drawing...
return (int)(((((uint)_x1) ^ ((((uint)_y1) << 13) |
(((uint)_y1) >> 0x13))) ^ ((((uint)_x2) << 0x1a) |
(((uint)_x2) >> 6))) ^ ((((uint)_y2) << 7) |
(((uint)_y2) >> 0x19)));
}
/// <summary>
/// Tests whether two structures have equal coordinates.
/// </summary>
public static bool operator ==(PdfRectangle left, PdfRectangle right)
{
// ReSharper disable CompareOfFloatsByEqualityOperator
// use: if (Object.ReferenceEquals(left, null))
if ((object)left != null)
{
if ((object)right != null)
return left._x1 == right._x1 && left._y1 == right._y1 && left._x2 == right._x2 && left._y2 == right._y2;
return false;
}
return (object)right == null;
// ReSharper restore CompareOfFloatsByEqualityOperator
}
/// <summary>
/// Tests whether two structures differ in one or more coordinates.
/// </summary>
public static bool operator !=(PdfRectangle left, PdfRectangle right)
{
return !(left == right);
}
/// <summary>
/// Gets or sets the x-coordinate of the first corner of this PdfRectangle.
/// </summary>
public double X1
{
get { return _x1; }
}
readonly double _x1;
/// <summary>
/// Gets or sets the y-coordinate of the first corner of this PdfRectangle.
/// </summary>
public double Y1
{
get { return _y1; }
}
readonly double _y1;
/// <summary>
/// Gets or sets the x-coordinate of the second corner of this PdfRectangle.
/// </summary>
public double X2
{
get { return _x2; }
}
readonly double _x2;
/// <summary>
/// Gets or sets the y-coordinate of the second corner of this PdfRectangle.
/// </summary>
public double Y2
{
get { return _y2; }
}
readonly double _y2;
/// <summary>
/// Gets X2 - X1.
/// </summary>
public double Width
{
get { return _x2 - _x1; }
}
/// <summary>
/// Gets Y2 - Y1.
/// </summary>
public double Height
{
get { return _y2 - _y1; }
}
/// <summary>
/// Gets or sets the coordinates of the first point of this PdfRectangle.
/// </summary>
public XPoint Location
{
get { return new XPoint(_x1, _y1); }
}
/// <summary>
/// Gets or sets the size of this PdfRectangle.
/// </summary>
public XSize Size
{
get { return new XSize(_x2 - _x1, _y2 - _y1); }
}
#if GDI
/// <summary>
/// Determines if the specified point is contained within this PdfRectangle.
/// </summary>
public bool Contains(PointF pt)
{
return Contains(pt.X, pt.Y);
}
#endif
/// <summary>
/// Determines if the specified point is contained within this PdfRectangle.
/// </summary>
public bool Contains(XPoint pt)
{
return Contains(pt.X, pt.Y);
}
/// <summary>
/// Determines if the specified point is contained within this PdfRectangle.
/// </summary>
public bool Contains(double x, double y)
{
// Treat rectangle inclusive/inclusive.
return _x1 <= x && x <= _x2 && _y1 <= y && y <= _y2;
}
#if GDI
/// <summary>
/// Determines if the rectangular region represented by rect is entirely contained within this PdfRectangle.
/// </summary>
public bool Contains(RectangleF rect)
{
return _x1 <= rect.X && (rect.X + rect.Width) <= _x2 &&
_y1 <= rect.Y && (rect.Y + rect.Height) <= _y2;
}
#endif
/// <summary>
/// Determines if the rectangular region represented by rect is entirely contained within this PdfRectangle.
/// </summary>
public bool Contains(XRect rect)
{
return _x1 <= rect.X && (rect.X + rect.Width) <= _x2 &&
_y1 <= rect.Y && (rect.Y + rect.Height) <= _y2;
}
/// <summary>
/// Determines if the rectangular region represented by rect is entirely contained within this PdfRectangle.
/// </summary>
public bool Contains(PdfRectangle rect)
{
return _x1 <= rect._x1 && rect._x2 <= _x2 &&
_y1 <= rect._y1 && rect._y2 <= _y2;
}
/// <summary>
/// Returns the rectangle as an XRect object.
/// </summary>
public XRect ToXRect()
{
return new XRect(_x1, _y1, Width, Height);
}
/// <summary>
/// Returns the rectangle as a string in the form <20>[x1 y1 x2 y2]<5D>.
/// </summary>
public override string ToString()
{
const string format = Config.SignificantFigures3;
return PdfEncoders.Format("[{0:" + format + "} {1:" + format + "} {2:" + format + "} {3:" + format + "}]", _x1, _y1, _x2, _y2);
}
/// <summary>
/// Writes the rectangle.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.Write(this);
}
/// <summary>
/// Gets the DebuggerDisplayAttribute text.
/// </summary>
// ReSharper disable UnusedMember.Local
string DebuggerDisplay
// ReSharper restore UnusedMember.Local
{
get
{
const string format = Config.SignificantFigures10;
return String.Format(CultureInfo.InvariantCulture,
"X1={0:" + format + "}, Y1={1:" + format + "}, X2={2:" + format + "}, Y2={3:" + format + "}", _x1, _y1, _x2, _y2);
}
}
#if false // This object is considered as immutable.
// /// <summary>
// /// Adjusts the location of this PdfRectangle by the specified amount.
// /// </summary>
// public void Offset(PointF pos)
// {
// Offset(pos.X, pos.Y);
// }
//
// /// <summary>
// /// Adjusts the location of this PdfRectangle by the specified amount.
// /// </summary>
// public void Offset(double x, double y)
// {
// _x1 += x;
// _y1 += y;
// _x2 += x;
// _y2 += y;
// }
//
// /// <summary>
// /// Inflates this PdfRectangle by the specified amount.
// /// </summary>
// public void Inflate(double x, double y)
// {
// _x1 -= x;
// _y1 -= y;
// _x2 += x;
// _y2 += y;
// }
//
// /// <summary>
// /// Inflates this PdfRectangle by the specified amount.
// /// </summary>
// public void Inflate(SizeF size)
// {
// Inflate(size.Width, size.Height);
// }
//
// /// <summary>
// /// Creates and returns an inflated copy of the specified PdfRectangle.
// /// </summary>
// public static PdfRectangle Inflate(PdfRectangle rect, double x, double y)
// {
// rect.Inflate(x, y);
// return rect;
// }
//
// /// <summary>
// /// Replaces this PdfRectangle with the intersection of itself and the specified PdfRectangle.
// /// </summary>
// public void Intersect(PdfRectangle rect)
// {
// PdfRectangle rect2 = PdfRectangle.Intersect(rect, this);
// _x1 = rect2.x1;
// _y1 = rect2.y1;
// _x2 = rect2.x2;
// _y2 = rect2.y2;
// }
//
// /// <summary>
// /// Returns a PdfRectangle that represents the intersection of two rectangles. If there is no intersection,
// /// an empty PdfRectangle is returned.
// /// </summary>
// public static PdfRectangle Intersect(PdfRectangle rect1, PdfRectangle rect2)
// {
// double xx1 = Math.Max(rect1.x1, rect2.x1);
// double xx2 = Math.Min(rect1.x2, rect2.x2);
// double yy1 = Math.Max(rect1.y1, rect2.y1);
// double yy2 = Math.Min(rect1.y2, rect2.y2);
// if (xx2 >= xx1 && yy2 >= yy1)
// return new PdfRectangle(xx1, yy1, xx2, yy2);
// return PdfRectangle.Empty;
// }
//
// /// <summary>
// /// Determines if this rectangle intersects with the specified PdfRectangle.
// /// </summary>
// public bool IntersectsWith(PdfRectangle rect)
// {
// return rect.x1 < _x2 && _x1 < rect.x2 && rect.y1 < _y2 && _y1 < rect.y2;
// }
//
// /// <summary>
// /// Creates the smallest rectangle that can contain both of two specified rectangles.
// /// </summary>
// public static PdfRectangle Union(PdfRectangle rect1, PdfRectangle rect2)
// {
// return new PdfRectangle(
// Math.Min(rect1.x1, rect2.x1), Math.Max(rect1.x2, rect2.x2),
// Math.Min(rect1.y1, rect2.y1), Math.Max(rect1.y2, rect2.y2));
// }
#endif
/// <summary>
/// Represents an empty PdfRectangle.
/// </summary>
public static readonly PdfRectangle Empty = new PdfRectangle();
}
}

View File

@@ -0,0 +1,560 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using PdfSharp.Pdf.Advanced;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
// NOT YET IN USE ANYMORE. REPLACEED PdfSharp.Pdf.Advanced.PdfCrossReferenceTable.
/// <summary>
/// Represents the cross-reference table of a PDF document.
/// It contains all indirect objects of a document.
/// </summary>
internal sealed class PdfReferenceTable_old // Must not be derive from PdfObject.
{
public PdfReferenceTable_old(PdfDocument document)
{
_document = document;
}
readonly PdfDocument _document;
/// <summary>
/// Represents the relation between PdfObjectID and PdfReference for a PdfDocument.
/// </summary>
public Dictionary<PdfObjectID, PdfReference> ObjectTable = new Dictionary<PdfObjectID, PdfReference>();
internal bool IsUnderConstruction
{
get { return _isUnderConstruction; }
set { _isUnderConstruction = value; }
}
bool _isUnderConstruction;
/// <summary>
/// Adds a cross reference entry to the table. Used when parsing the trailer.
/// </summary>
public void Add(PdfReference iref)
{
if (iref.ObjectID.IsEmpty)
iref.ObjectID = new PdfObjectID(GetNewObjectNumber());
if (ObjectTable.ContainsKey(iref.ObjectID))
throw new InvalidOperationException("Object already in table.");
ObjectTable.Add(iref.ObjectID, iref);
}
/// <summary>
/// Adds a PdfObject to the table.
/// </summary>
public void Add(PdfObject value)
{
if (value.Owner == null)
value.Document = _document;
else
Debug.Assert(value.Owner == _document);
if (value.ObjectID.IsEmpty)
value.SetObjectID(GetNewObjectNumber(), 0);
if (ObjectTable.ContainsKey(value.ObjectID))
throw new InvalidOperationException("Object already in table.");
ObjectTable.Add(value.ObjectID, value.Reference);
}
public void Remove(PdfReference iref)
{
ObjectTable.Remove(iref.ObjectID);
}
/// <summary>
/// Gets a cross reference entry from an object identifier.
/// Returns null if no object with the specified ID exists in the object table.
/// </summary>
public PdfReference this[PdfObjectID objectID]
{
get
{
PdfReference iref;
ObjectTable.TryGetValue(objectID, out iref);
return iref;
}
}
/// <summary>
/// Indicates whether the specified object identifier is in the table.
/// </summary>
public bool Contains(PdfObjectID objectID)
{
return ObjectTable.ContainsKey(objectID);
}
//public PdfObject GetObject(PdfObjectID objectID)
//{
// return this[objectID].Value;
//}
// /// <summary>
// /// Gets the entry for the specified object, or null, if the object is not in
// /// this XRef table.
// /// </summary>
// internal PdfReference GetEntry(PdfObjectID objectID)
// {
// return this[objectID];
// }
/// <summary>
/// Returns the next free object number.
/// </summary>
public int GetNewObjectNumber()
{
// New objects are numbered consecutively. If a document is imported, maxObjectNumber is
// set to the highest object number used in the document.
return ++_maxObjectNumber;
}
internal int _maxObjectNumber;
/// <summary>
/// Writes the xref section in pdf stream.
/// </summary>
internal void WriteObject(PdfWriter writer)
{
writer.WriteRaw("xref\n");
PdfReference[] irefs = AllReferences;
int count = irefs.Length;
writer.WriteRaw(String.Format("0 {0}\n", count + 1));
writer.WriteRaw(String.Format("{0:0000000000} {1:00000} {2} \n", 0, 65535, "f"));
//PdfEncoders.WriteAnsi(stream, text);
for (int idx = 0; idx < count; idx++)
{
PdfReference iref = irefs[idx];
// Acrobat is very pedantic; it must be exactly 20 bytes per line.
writer.WriteRaw(String.Format("{0:0000000000} {1:00000} {2} \n", iref.Position, iref.GenerationNumber, "n"));
}
}
/// <summary>
/// Gets an array of all object identifier. For debugging purposes only.
/// </summary>
internal PdfObjectID[] AllObjectIDs
{
get
{
ICollection collection = ObjectTable.Keys;
PdfObjectID[] objectIDs = new PdfObjectID[collection.Count];
collection.CopyTo(objectIDs, 0);
return objectIDs;
}
}
/// <summary>
/// Gets an array of all cross references in ascending order by their object identifier.
/// </summary>
internal PdfReference[] AllReferences
{
get
{
Dictionary<PdfObjectID, PdfReference>.ValueCollection collection = ObjectTable.Values;
List<PdfReference> list = new List<PdfReference>(collection);
list.Sort(PdfReference.Comparer);
PdfReference[] irefs = new PdfReference[collection.Count];
list.CopyTo(irefs, 0);
return irefs;
}
}
internal void HandleOrphanedReferences()
{ }
/// <summary>
/// Removes all objects that cannot be reached from the trailer.
/// Returns the number of removed objects.
/// </summary>
internal int Compact()
{
// TODO: remove PdfBooleanObject, PdfIntegerObject etc.
int removed = ObjectTable.Count;
//CheckConsistence();
// TODO: Is this really so easy?
PdfReference[] irefs = TransitiveClosure(_document._trailer);
#if DEBUG
// Have any two objects the same ID?
Dictionary<int, int> ids = new Dictionary<int, int>();
foreach (PdfObjectID objID in ObjectTable.Keys)
{
ids.Add(objID.ObjectNumber, 0);
}
// Have any two irefs the same value?
//Dictionary<int, int> ids = new Dictionary<int, int>();
ids.Clear();
foreach (PdfReference iref in ObjectTable.Values)
{
ids.Add(iref.ObjectNumber, 0);
}
//
Dictionary<PdfReference, int> refs = new Dictionary<PdfReference, int>();
foreach (PdfReference iref in irefs)
{
refs.Add(iref, 0);
}
foreach (PdfReference value in ObjectTable.Values)
{
if (!refs.ContainsKey(value))
value.GetType();
}
foreach (PdfReference iref in ObjectTable.Values)
{
if (iref.Value == null)
GetType();
Debug.Assert(iref.Value != null);
}
foreach (PdfReference iref in irefs)
{
if (!ObjectTable.ContainsKey(iref.ObjectID))
GetType();
Debug.Assert(ObjectTable.ContainsKey(iref.ObjectID));
if (iref.Value == null)
GetType();
Debug.Assert(iref.Value != null);
}
#endif
_maxObjectNumber = 0;
ObjectTable.Clear();
foreach (PdfReference iref in irefs)
{
// This if is needed for corrupt PDF files from the wild.
// Without the if, an exception will be thrown if the file contains duplicate IDs ("An item with the same key has already been added to the dictionary.").
// With the if, the first object with the ID will be used and later objects with the same ID will be ignored.
if (!ObjectTable.ContainsKey(iref.ObjectID))
{
ObjectTable.Add(iref.ObjectID, iref);
_maxObjectNumber = Math.Max(_maxObjectNumber, iref.ObjectNumber);
}
}
//CheckConsistence();
removed -= ObjectTable.Count;
return removed;
}
/// <summary>
/// Renumbers the objects starting at 1.
/// </summary>
internal void Renumber()
{
//CheckConsistence();
PdfReference[] irefs = AllReferences;
ObjectTable.Clear();
// Give all objects a new number.
int count = irefs.Length;
for (int idx = 0; idx < count; idx++)
{
PdfReference iref = irefs[idx];
#if DEBUG_
if (iref.ObjectNumber == 1108)
GetType();
#endif
iref.ObjectID = new PdfObjectID(idx + 1);
// Rehash with new number.
ObjectTable.Add(iref.ObjectID, iref);
}
_maxObjectNumber = count;
//CheckConsistence();
}
/// <summary>
/// Checks the logical consistence for debugging purposes (useful after reconstruction work).
/// </summary>
[Conditional("DEBUG_")]
public void CheckConsistence()
{
Dictionary<PdfReference, object> ht1 = new Dictionary<PdfReference, object>();
foreach (PdfReference iref in ObjectTable.Values)
{
Debug.Assert(!ht1.ContainsKey(iref), "Duplicate iref.");
Debug.Assert(iref.Value != null);
ht1.Add(iref, null);
}
Dictionary<PdfObjectID, object> ht2 = new Dictionary<PdfObjectID, object>();
foreach (PdfReference iref in ObjectTable.Values)
{
Debug.Assert(!ht2.ContainsKey(iref.ObjectID), "Duplicate iref.");
ht2.Add(iref.ObjectID, null);
}
ICollection collection = ObjectTable.Values;
int count = collection.Count;
PdfReference[] irefs = new PdfReference[count];
collection.CopyTo(irefs, 0);
#if true
for (int i = 0; i < count; i++)
for (int j = 0; j < count; j++)
if (i != j)
{
Debug.Assert(ReferenceEquals(irefs[i].Document, _document));
Debug.Assert(irefs[i] != irefs[j]);
Debug.Assert(!ReferenceEquals(irefs[i], irefs[j]));
Debug.Assert(!ReferenceEquals(irefs[i].Value, irefs[j].Value));
Debug.Assert(!Equals(irefs[i].ObjectID, irefs[j].Value.ObjectID));
Debug.Assert(irefs[i].ObjectNumber != irefs[j].Value.ObjectNumber);
Debug.Assert(ReferenceEquals(irefs[i].Document, irefs[j].Document));
GetType();
}
#endif
}
///// <summary>
///// The garbage collector for PDF objects.
///// </summary>
//public sealed class GC
//{
// PdfXRefTable xrefTable;
//
// internal GC(PdfXRefTable xrefTable)
// {
// _xrefTable = xrefTable;
// }
//
// public void Collect()
// { }
//
// public PdfReference[] ReachableObjects()
// {
// Hash_table objects = new Hash_table();
// TransitiveClosure(objects, _xrefTable.document.trailer);
// }
/// <summary>
/// Calculates the transitive closure of the specified PdfObject, i.e. all indirect objects
/// recursively reachable from the specified object.
/// </summary>
public PdfReference[] TransitiveClosure(PdfObject pdfObject)
{
return TransitiveClosure(pdfObject, Int16.MaxValue);
}
/// <summary>
/// Calculates the transitive closure of the specified PdfObject with the specified depth, i.e. all indirect objects
/// recursively reachable from the specified object in up to maximally depth steps.
/// </summary>
public PdfReference[] TransitiveClosure(PdfObject pdfObject, int depth)
{
CheckConsistence();
Dictionary<PdfItem, object> objects = new Dictionary<PdfItem, object>();
_overflow = new Dictionary<PdfItem, object>();
TransitiveClosureImplementation(objects, pdfObject /*, ref depth*/);
TryAgain:
if (_overflow.Count > 0)
{
PdfObject[] array = new PdfObject[_overflow.Count];
_overflow.Keys.CopyTo(array, 0);
_overflow = new Dictionary<PdfItem, object>();
for (int idx = 0; idx < array.Length; idx++)
{
PdfObject obj = array[idx];
TransitiveClosureImplementation(objects, obj /*, ref depth*/);
}
goto TryAgain;
}
CheckConsistence();
ICollection collection = objects.Keys;
int count = collection.Count;
PdfReference[] irefs = new PdfReference[count];
collection.CopyTo(irefs, 0);
#if true_
for (int i = 0; i < count; i++)
for (int j = 0; j < count; j++)
if (i != j)
{
Debug.Assert(ReferenceEquals(irefs[i].Document, _document));
Debug.Assert(irefs[i] != irefs[j]);
Debug.Assert(!ReferenceEquals(irefs[i], irefs[j]));
Debug.Assert(!ReferenceEquals(irefs[i].Value, irefs[j].Value));
Debug.Assert(!Equals(irefs[i].ObjectID, irefs[j].Value.ObjectID));
Debug.Assert(irefs[i].ObjectNumber != irefs[j].Value.ObjectNumber);
Debug.Assert(ReferenceEquals(irefs[i].Document, irefs[j].Document));
GetType();
}
#endif
return irefs;
}
static int _nestingLevel;
Dictionary<PdfItem, object> _overflow = new Dictionary<PdfItem, object>();
void TransitiveClosureImplementation(Dictionary<PdfItem, object> objects, PdfObject pdfObject/*, ref int depth*/)
{
try
{
_nestingLevel++;
if (_nestingLevel >= 1000)
{
if (!_overflow.ContainsKey(pdfObject))
_overflow.Add(pdfObject, null);
return;
}
#if DEBUG_
//enterCount++;
if (enterCount == 5400)
GetType();
//if (!Object.ReferenceEquals(pdfObject.Owner, _document))
// GetType();
//////Debug.Assert(Object.ReferenceEquals(pdfObject27.Document, _document));
// if (item is PdfObject && ((PdfObject)item).ObjectID.ObjectNumber == 5)
// Debug.WriteLine("items: " + ((PdfObject)item).ObjectID.ToString());
//if (pdfObject.ObjectNumber == 5)
// GetType();
#endif
IEnumerable enumerable = null; //(IEnumerator)pdfObject;
PdfDictionary dict;
PdfArray array;
if ((dict = pdfObject as PdfDictionary) != null)
enumerable = dict.Elements.Values;
else if ((array = pdfObject as PdfArray) != null)
enumerable = array.Elements;
else
Debug.Assert(false, "Should not come here.");
if (enumerable != null)
{
foreach (PdfItem item in enumerable)
{
PdfReference iref = item as PdfReference;
if (iref != null)
{
// Is this an indirect reference to an object that does not exist?
//if (iref.Document == null)
//{
// Debug.WriteLine("Dead object detected: " + iref.ObjectID.ToString());
// PdfReference dead = DeadObject;
// iref.ObjectID = dead.ObjectID;
// iref.Document = _document;
// iref.SetObject(dead.Value);
// PdfDictionary dict = (PdfDictionary)dead.Value;
// dict.Elements["/DeadObjectCount"] =
// new PdfInteger(dict.Elements.GetInteger("/DeadObjectCount") + 1);
// iref = dead;
//}
if (!ReferenceEquals(iref.Document, _document))
{
GetType();
Debug.WriteLine(String.Format("Bad iref: {0}", iref.ObjectID.ToString()));
}
Debug.Assert(ReferenceEquals(iref.Document, _document) || iref.Document == null, "External object detected!");
#if DEBUG_
if (iref.ObjectID.ObjectNumber == 23)
GetType();
#endif
if (!objects.ContainsKey(iref))
{
PdfObject value = iref.Value;
// Ignore unreachable objects.
if (iref.Document != null)
{
// ... from trailer hack
if (value == null)
{
iref = ObjectTable[iref.ObjectID];
Debug.Assert(iref.Value != null);
value = iref.Value;
}
Debug.Assert(ReferenceEquals(iref.Document, _document));
objects.Add(iref, null);
//Debug.WriteLine(String.Format("objects.Add('{0}', null);", iref.ObjectID.ToString()));
if (value is PdfArray || value is PdfDictionary)
TransitiveClosureImplementation(objects, value /*, ref depth*/);
}
//else
//{
// objects2.Add(this[iref.ObjectID], null);
//}
}
}
else
{
PdfObject pdfObject28 = item as PdfObject;
//if (pdfObject28 != null)
// Debug.Assert(Object.ReferenceEquals(pdfObject28.Document, _document));
if (pdfObject28 != null && (pdfObject28 is PdfDictionary || pdfObject28 is PdfArray))
TransitiveClosureImplementation(objects, pdfObject28 /*, ref depth*/);
}
}
}
}
finally
{
_nestingLevel--;
}
}
/// <summary>
/// Gets the cross reference to an objects used for undefined indirect references.
/// </summary>
public PdfReference DeadObject
{
get
{
if (_deadObject == null)
{
_deadObject = new PdfDictionary(_document);
Add(_deadObject);
_deadObject.Elements.Add("/DeadObjectCount", new PdfInteger());
}
return _deadObject.Reference;
}
}
PdfDictionary _deadObject;
}
}

327
PdfSharp/Pdf/PdfString.cs Normal file
View File

@@ -0,0 +1,327 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using System.Text;
using PdfSharp.Pdf.IO;
using PdfSharp.Pdf.Internal;
namespace PdfSharp.Pdf
{
/// <summary>
/// Determines the encoding of a PdfString or PdfStringObject.
/// </summary>
[Flags]
public enum PdfStringEncoding
{
/// <summary>
/// The characters of the string are actually bytes with an unknown or context specific meaning or encoding.
/// With this encoding the 8 high bits of each character is zero.
/// </summary>
RawEncoding = PdfStringFlags.RawEncoding,
/// <summary>
/// Not yet used by PDFsharp.
/// </summary>
StandardEncoding = PdfStringFlags.StandardEncoding,
/// <summary>
/// The characters of the string are actually bytes with PDF document encoding.
/// With this encoding the 8 high bits of each character is zero.
/// </summary>
// ReSharper disable InconsistentNaming because the name is spelled as in the Adobe reference.
PDFDocEncoding = PdfStringFlags.PDFDocEncoding,
// ReSharper restore InconsistentNaming
/// <summary>
/// The characters of the string are actually bytes with Windows ANSI encoding.
/// With this encoding the 8 high bits of each character is zero.
/// </summary>
WinAnsiEncoding = PdfStringFlags.WinAnsiEncoding,
/// <summary>
/// Not yet used by PDFsharp.
/// </summary>
MacRomanEncoding = PdfStringFlags.MacExpertEncoding,
/// <summary>
/// Not yet used by PDFsharp.
/// </summary>
MacExpertEncoding = PdfStringFlags.MacExpertEncoding,
/// <summary>
/// The characters of the string are Unicode characters.
/// </summary>
Unicode = PdfStringFlags.Unicode,
}
/// <summary>
/// Internal wrapper for PdfStringEncoding.
/// </summary>
[Flags]
enum PdfStringFlags
{
// ReSharper disable InconsistentNaming
RawEncoding = 0x00,
StandardEncoding = 0x01, // not used by PDFsharp
PDFDocEncoding = 0x02,
WinAnsiEncoding = 0x03,
MacRomanEncoding = 0x04, // not used by PDFsharp
MacExpertEncoding = 0x05, // not used by PDFsharp
Unicode = 0x06,
EncodingMask = 0x0F,
HexLiteral = 0x80,
// ReSharper restore InconsistentNaming
}
/// <summary>
/// Represents a direct text string value.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfString : PdfItem
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfString"/> class.
/// </summary>
public PdfString()
{
// Redundant assignment.
//_flags = PdfStringFlags.RawEncoding;
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfString"/> class.
/// </summary>
/// <param name="value">The value.</param>
public PdfString(string value)
{
#if true
if (!IsRawEncoding(value))
_flags = PdfStringFlags.Unicode;
_value = value;
#else
CheckRawEncoding(value);
_value = value;
//_flags = PdfStringFlags.RawEncoding;
#endif
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfString"/> class.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="encoding">The encoding.</param>
public PdfString(string value, PdfStringEncoding encoding)
{
switch (encoding)
{
case PdfStringEncoding.RawEncoding:
CheckRawEncoding(value);
break;
case PdfStringEncoding.StandardEncoding:
break;
case PdfStringEncoding.PDFDocEncoding:
break;
case PdfStringEncoding.WinAnsiEncoding:
CheckRawEncoding(value);
break;
case PdfStringEncoding.MacRomanEncoding:
break;
case PdfStringEncoding.Unicode:
break;
default:
throw new ArgumentOutOfRangeException("encoding");
}
_value = value;
//if ((flags & PdfStringFlags.EncodingMask) == 0)
// flags |= PdfStringFlags.PDFDocEncoding;
_flags = (PdfStringFlags)encoding;
}
internal PdfString(string value, PdfStringFlags flags)
{
_value = value;
_flags = flags;
}
/// <summary>
/// Gets the number of characters in this string.
/// </summary>
public int Length
{
get { return _value == null ? 0 : _value.Length; }
}
/// <summary>
/// Gets the encoding.
/// </summary>
public PdfStringEncoding Encoding
{
get { return (PdfStringEncoding)(_flags & PdfStringFlags.EncodingMask); }
}
/// <summary>
/// Gets a value indicating whether the string is a hexadecimal literal.
/// </summary>
public bool HexLiteral
{
get { return (_flags & PdfStringFlags.HexLiteral) != 0; }
}
internal PdfStringFlags Flags
{
get { return _flags; }
}
readonly PdfStringFlags _flags;
/// <summary>
/// Gets the string value.
/// </summary>
public string Value
{
// This class must behave like a value type. Therefore it cannot be changed (like System.String).
get { return _value ?? ""; }
}
string _value;
/// <summary>
/// Gets or sets the string value for encryption purposes.
/// </summary>
internal byte[] EncryptionValue
{
// TODO: Unicode case is not handled!
get { return _value == null ? new byte[0] : PdfEncoders.RawEncoding.GetBytes(_value); }
// BUG: May lead to trouble with the value semantics of PdfString
set { _value = PdfEncoders.RawEncoding.GetString(value, 0, value.Length); }
}
/// <summary>
/// Returns the string.
/// </summary>
public override string ToString()
{
#if true
PdfStringEncoding encoding = (PdfStringEncoding)(_flags & PdfStringFlags.EncodingMask);
string pdf = (_flags & PdfStringFlags.HexLiteral) == 0 ?
PdfEncoders.ToStringLiteral(_value, encoding, null) :
PdfEncoders.ToHexStringLiteral(_value, encoding, null);
return pdf;
#else
return _value;
#endif
}
/// <summary>
/// Hack for document encoded bookmarks.
/// </summary>
public string ToStringFromPdfDocEncoded()
{
int length = _value.Length;
char[] bytes = new char[length];
for (int idx = 0; idx < length; idx++)
{
char ch = _value[idx];
if (ch <= 255)
{
bytes[idx] = Encode[ch];
}
else
{
//Debug-Break.Break();
throw new InvalidOperationException("DocEncoded string contains char greater 255.");
}
}
StringBuilder sb = new StringBuilder(length);
for (int idx = 0; idx < length; idx++)
sb.Append((char)bytes[idx]);
return sb.ToString();
}
static readonly char[] Encode =
{
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0A', '\x0B', '\x0C', '\x0D', '\x0E', '\x0F',
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1A', '\x1B', '\x1C', '\x1D', '\x1E', '\x1F',
'\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', '\x28', '\x29', '\x2A', '\x2B', '\x2C', '\x2D', '\x2E', '\x2F',
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39', '\x3A', '\x3B', '\x3C', '\x3D', '\x3E', '\x3F',
'\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', '\x48', '\x49', '\x4A', '\x4B', '\x4C', '\x4D', '\x4E', '\x4F',
'\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', '\x58', '\x59', '\x5A', '\x5B', '\x5C', '\x5D', '\x5E', '\x5F',
'\x60', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', '\x69', '\x6A', '\x6B', '\x6C', '\x6D', '\x6E', '\x6F',
'\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', '\x78', '\x79', '\x7A', '\x7B', '\x7C', '\x7D', '\x7E', '\x7F',
'\x2022', '\x2020', '\x2021', '\x2026', '\x2014', '\x2013', '\x0192', '\x2044', '\x2039', '\x203A', '\x2212', '\x2030', '\x201E', '\x201C', '\x201D', '\x2018',
'\x2019', '\x201A', '\x2122', '\xFB01', '\xFB02', '\x0141', '\x0152', '\x0160', '\x0178', '\x017D', '\x0131', '\x0142', '\x0153', '\x0161', '\x017E', '\xFFFD',
'\x20AC', '\xA1', '\xA2', '\xA3', '\xA4', '\xA5', '\xA6', '\xA7', '\xA8', '\xA9', '\xAA', '\xAB', '\xAC', '\xAD', '\xAE', '\xAF',
'\xB0', '\xB1', '\xB2', '\xB3', '\xB4', '\xB5', '\xB6', '\xB7', '\xB8', '\xB9', '\xBA', '\xBB', '\xBC', '\xBD', '\xBE', '\xBF',
'\xC0', '\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7', '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE', '\xCF',
'\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5', '\xD6', '\xD7', '\xD8', '\xD9', '\xDA', '\xDB', '\xDC', '\xDD', '\xDE', '\xDF',
'\xE0', '\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7', '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE', '\xEF',
'\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5', '\xF6', '\xF7', '\xF8', '\xF9', '\xFA', '\xFB', '\xFC', '\xFD', '\xFE', '\xFF',
};
static void CheckRawEncoding(string s)
{
if (String.IsNullOrEmpty(s))
return;
int length = s.Length;
for (int idx = 0; idx < length; idx++)
{
Debug.Assert(s[idx] < 256, "RawString contains invalid character.");
}
}
static bool IsRawEncoding(string s)
{
if (String.IsNullOrEmpty(s))
return true;
int length = s.Length;
for (int idx = 0; idx < length; idx++)
{
if (!(s[idx] < 256))
return false;
}
return true;
}
/// <summary>
/// Writes the string DocEncoded.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.Write(this);
}
}
}

View File

@@ -0,0 +1,149 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System.Diagnostics;
using PdfSharp.Pdf.IO;
using PdfSharp.Pdf.Internal;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents an indirect text string value. This type is not used by PDFsharp. If it is imported from
/// an external PDF file, the value is converted into a direct object.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfStringObject : PdfObject
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfStringObject"/> class.
/// </summary>
public PdfStringObject()
{
_flags = PdfStringFlags.RawEncoding;
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfStringObject"/> class.
/// </summary>
/// <param name="document">The document.</param>
/// <param name="value">The value.</param>
public PdfStringObject(PdfDocument document, string value)
: base(document)
{
_value = value;
_flags = PdfStringFlags.RawEncoding;
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfStringObject"/> class.
/// </summary>
/// <param name="value">The value.</param>
/// <param name="encoding">The encoding.</param>
public PdfStringObject(string value, PdfStringEncoding encoding)
{
_value = value;
//if ((flags & PdfStringFlags.EncodingMask) == 0)
// flags |= PdfStringFlags.PDFDocEncoding;
_flags = (PdfStringFlags)encoding;
}
internal PdfStringObject(string value, PdfStringFlags flags)
{
_value = value;
//if ((flags & PdfStringFlags.EncodingMask) == 0)
// flags |= PdfStringFlags.PDFDocEncoding;
_flags = flags;
}
/// <summary>
/// Gets the number of characters in this string.
/// </summary>
public int Length
{
get { return _value == null ? 0 : _value.Length; }
}
/// <summary>
/// Gets or sets the encoding.
/// </summary>
public PdfStringEncoding Encoding
{
get { return (PdfStringEncoding)(_flags & PdfStringFlags.EncodingMask); }
set { _flags = (_flags & ~PdfStringFlags.EncodingMask) | ((PdfStringFlags)value & PdfStringFlags.EncodingMask); }
}
/// <summary>
/// Gets a value indicating whether the string is a hexadecimal literal.
/// </summary>
public bool HexLiteral
{
get { return (_flags & PdfStringFlags.HexLiteral) != 0; }
set { _flags = value ? _flags | PdfStringFlags.HexLiteral : _flags & ~PdfStringFlags.HexLiteral; }
}
PdfStringFlags _flags;
/// <summary>
/// Gets or sets the value as string
/// </summary>
public string Value
{
get { return _value ?? ""; }
set { _value = value ?? ""; }
}
string _value;
/// <summary>
/// Gets or sets the string value for encryption purposes.
/// </summary>
internal byte[] EncryptionValue
{
// TODO: Unicode case is not handled!
get { return _value == null ? new byte[0] : PdfEncoders.RawEncoding.GetBytes(_value); }
set { _value = PdfEncoders.RawEncoding.GetString(value, 0, value.Length); }
}
/// <summary>
/// Returns the string.
/// </summary>
public override string ToString()
{
return _value;
}
/// <summary>
/// Writes the string literal with encoding DOCEncoded.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.WriteBeginObject(this);
writer.Write(new PdfString(_value, _flags));
writer.WriteEndObject();
}
}
}

228
PdfSharp/Pdf/PdfUInteger.cs Normal file
View File

@@ -0,0 +1,228 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Diagnostics;
using System.Globalization;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents a direct unsigned integer value.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfUInteger : PdfNumber, IConvertible
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfUInteger"/> class.
/// </summary>
public PdfUInteger()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfUInteger"/> class.
/// </summary>
public PdfUInteger(uint value)
{
_value = value;
}
/// <summary>
/// Gets the value as integer.
/// </summary>
public uint Value
{
// This class must behave like a value type. Therefore it cannot be changed (like System.String).
get { return _value; }
}
readonly uint _value;
/// <summary>
/// Returns the unsigned integer as string.
/// </summary>
public override string ToString()
{
// ToString is impure but does not change the value of _value.
// ReSharper disable ImpureMethodCallOnReadonlyValueField
return _value.ToString(CultureInfo.InvariantCulture);
// ReSharper restore ImpureMethodCallOnReadonlyValueField
}
/// <summary>
/// Writes the integer as string.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.Write(this);
}
#region IConvertible Members
/// <summary>
/// Converts the value of this instance to an equivalent 64-bit unsigned integer.
/// </summary>
public ulong ToUInt64(IFormatProvider provider)
{
return Convert.ToUInt64(_value);
}
/// <summary>
/// Converts the value of this instance to an equivalent 8-bit signed integer.
/// </summary>
public sbyte ToSByte(IFormatProvider provider)
{
throw new InvalidCastException();
}
/// <summary>
/// Converts the value of this instance to an equivalent double-precision floating-point number.
/// </summary>
public double ToDouble(IFormatProvider provider)
{
return _value;
}
/// <summary>
/// Returns an undefined DateTime structure.
/// </summary>
public DateTime ToDateTime(IFormatProvider provider)
{
// TODO: Add PdfUInteger.ToDateTime implementation
return new DateTime();
}
/// <summary>
/// Converts the value of this instance to an equivalent single-precision floating-point number.
/// </summary>
public float ToSingle(IFormatProvider provider)
{
return _value;
}
/// <summary>
/// Converts the value of this instance to an equivalent Boolean value.
/// </summary>
public bool ToBoolean(IFormatProvider provider)
{
return Convert.ToBoolean(_value);
}
/// <summary>
/// Converts the value of this instance to an equivalent 32-bit signed integer.
/// </summary>
public int ToInt32(IFormatProvider provider)
{
return Convert.ToInt32(_value);
}
/// <summary>
/// Converts the value of this instance to an equivalent 16-bit unsigned integer.
/// </summary>
public ushort ToUInt16(IFormatProvider provider)
{
return Convert.ToUInt16(_value);
}
/// <summary>
/// Converts the value of this instance to an equivalent 16-bit signed integer.
/// </summary>
public short ToInt16(IFormatProvider provider)
{
return Convert.ToInt16(_value);
}
/// <summary>
/// Converts the value of this instance to an equivalent <see cref="T:System.String"></see>.
/// </summary>
string IConvertible.ToString(IFormatProvider provider)
{
return _value.ToString(provider);
}
/// <summary>
/// Converts the value of this instance to an equivalent 8-bit unsigned integer.
/// </summary>
public byte ToByte(IFormatProvider provider)
{
return Convert.ToByte(_value);
}
/// <summary>
/// Converts the value of this instance to an equivalent Unicode character.
/// </summary>
public char ToChar(IFormatProvider provider)
{
return Convert.ToChar(_value);
}
/// <summary>
/// Converts the value of this instance to an equivalent 64-bit signed integer.
/// </summary>
public long ToInt64(IFormatProvider provider)
{
return _value;
}
/// <summary>
/// Returns type code for 32-bit integers.
/// </summary>
public TypeCode GetTypeCode()
{
return TypeCode.Int32;
}
/// <summary>
/// Converts the value of this instance to an equivalent <see cref="T:System.Decimal"></see> number.
/// </summary>
public decimal ToDecimal(IFormatProvider provider)
{
return _value;
}
/// <summary>
/// Returns null.
/// </summary>
public object ToType(Type conversionType, IFormatProvider provider)
{
// TODO: Add PdfUInteger.ToType implementation
return null;
}
/// <summary>
/// Converts the value of this instance to an equivalent 32-bit unsigned integer.
/// </summary>
public uint ToUInt32(IFormatProvider provider)
{
return Convert.ToUInt32(_value);
}
#endregion
}
}

View File

@@ -0,0 +1,96 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System.Diagnostics;
using System.Globalization;
using PdfSharp.Pdf.IO;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents an indirect integer value. This type is not used by PDFsharp. If it is imported from
/// an external PDF file, the value is converted into a direct object.
/// </summary>
[DebuggerDisplay("({Value})")]
public sealed class PdfUIntegerObject : PdfNumberObject
{
/// <summary>
/// Initializes a new instance of the <see cref="PdfUIntegerObject"/> class.
/// </summary>
public PdfUIntegerObject()
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfUIntegerObject"/> class.
/// </summary>
/// <param name="value">The value.</param>
public PdfUIntegerObject(uint value)
{
_value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="PdfUIntegerObject"/> class.
/// </summary>
/// <param name="document">The document.</param>
/// <param name="value">The value.</param>
public PdfUIntegerObject(PdfDocument document, uint value)
: base(document)
{
_value = value;
}
/// <summary>
/// Gets the value as unsigned integer.
/// </summary>
public uint Value
{
get { return _value; }
}
readonly uint _value;
/// <summary>
/// Returns the integer as string.
/// </summary>
public override string ToString()
{
return _value.ToString(CultureInfo.InvariantCulture);
}
/// <summary>
/// Writes the integer literal.
/// </summary>
internal override void WriteObject(PdfWriter writer)
{
writer.WriteBeginObject(this);
writer.Write(_value);
writer.WriteEndObject();
}
}
}

View File

@@ -0,0 +1,308 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents the PDF document viewer preferences dictionary.
/// </summary>
public sealed class PdfViewerPreferences : PdfDictionary
{
internal PdfViewerPreferences(PdfDocument document)
: base(document)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="PdfViewerPreferences"/> class.
/// </summary>
PdfViewerPreferences(PdfDictionary dict)
: base(dict)
{ }
/// <summary>
/// Gets or sets a value indicating whether to hide the viewer application<6F>s tool
/// bars when the document is active.
/// </summary>
public bool HideToolbar
{
get { return Elements.GetBoolean(Keys.HideToolbar); }
set { Elements.SetBoolean(Keys.HideToolbar, value); }
}
/// <summary>
/// Gets or sets a value indicating whether to hide the viewer application<6F>s
/// menu bar when the document is active.
/// </summary>
public bool HideMenubar
{
get { return Elements.GetBoolean(Keys.HideMenubar); }
set { Elements.SetBoolean(Keys.HideMenubar, value); }
}
/// <summary>
/// Gets or sets a value indicating whether to hide user interface elements in
/// the document<6E>s window (such as scroll bars and navigation controls),
/// leaving only the document<6E>s contents displayed.
/// </summary>
public bool HideWindowUI
{
get { return Elements.GetBoolean(Keys.HideWindowUI); }
set { Elements.SetBoolean(Keys.HideWindowUI, value); }
}
/// <summary>
/// Gets or sets a value indicating whether to resize the document<6E>s window to
/// fit the size of the first displayed page.
/// </summary>
public bool FitWindow
{
get { return Elements.GetBoolean(Keys.FitWindow); }
set { Elements.SetBoolean(Keys.FitWindow, value); }
}
/// <summary>
/// Gets or sets a value indicating whether to position the document<6E>s window
/// in the center of the screen.
/// </summary>
public bool CenterWindow
{
get { return Elements.GetBoolean(Keys.CenterWindow); }
set { Elements.SetBoolean(Keys.CenterWindow, value); }
}
/// <summary>
/// Gets or sets a value indicating whether the window<6F>s title bar
/// should display the document title taken from the Title entry of the document
/// information dictionary. If false, the title bar should instead display the name
/// of the PDF file containing the document.
/// </summary>
public bool DisplayDocTitle
{
get { return Elements.GetBoolean(Keys.DisplayDocTitle); }
set { Elements.SetBoolean(Keys.DisplayDocTitle, value); }
}
/// <summary>
/// The predominant reading order for text: LeftToRight or RightToLeft
/// (including vertical writing systems, such as Chinese, Japanese, and Korean).
/// This entry has no direct effect on the document<6E>s contents or page numbering
/// but can be used to determine the relative positioning of pages when displayed
/// side by side or printed n-up. Default value: LeftToRight.
/// </summary>
public PdfReadingDirection? Direction
{
get
{
switch (Elements.GetName(Keys.Direction))
{
case "L2R":
return PdfReadingDirection.LeftToRight;
case "R2L":
return PdfReadingDirection.RightToLeft;
}
return null;
}
set
{
if (value.HasValue)
{
switch (value.Value)
{
case PdfReadingDirection.RightToLeft:
Elements.SetName(Keys.Direction, "R2L");
break;
default:
Elements.SetName(Keys.Direction, "L2R");
break;
}
}
else
Elements.Remove(Keys.Direction);
}
}
/// <summary>
/// Predefined keys of this dictionary.
/// </summary>
internal sealed class Keys : KeysBase
{
/// <summary>
/// (Optional) A flag specifying whether to hide the viewer application<6F>s tool
/// bars when the document is active. Default value: false.
/// </summary>
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
public const string HideToolbar = "/HideToolbar";
/// <summary>
/// (Optional) A flag specifying whether to hide the viewer application<6F>s
/// menu bar when the document is active. Default value: false.
/// </summary>
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
public const string HideMenubar = "/HideMenubar";
/// <summary>
/// (Optional) A flag specifying whether to hide user interface elements in
/// the document<6E>s window (such as scroll bars and navigation controls),
/// leaving only the document<6E>s contents displayed. Default value: false.
/// </summary>
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
public const string HideWindowUI = "/HideWindowUI";
/// <summary>
/// (Optional) A flag specifying whether to resize the document<6E>s window to
/// fit the size of the first displayed page. Default value: false.
/// </summary>
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
public const string FitWindow = "/FitWindow";
/// <summary>
/// (Optional) A flag specifying whether to position the document<6E>s window
/// in the center of the screen. Default value: false.
/// </summary>
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
public const string CenterWindow = "/CenterWindow";
/// <summary>
/// (Optional; PDF 1.4) A flag specifying whether the window<6F>s title bar
/// should display the document title taken from the Title entry of the document
/// information dictionary. If false, the title bar should instead display the name
/// of the PDF file containing the document. Default value: false.
/// </summary>
[KeyInfo(KeyType.Boolean | KeyType.Optional)]
public const string DisplayDocTitle = "/DisplayDocTitle";
/// <summary>
/// (Optional) The document<6E>s page mode, specifying how to display the document on
/// exiting full-screen mode:
/// UseNone Neither document outline nor thumbnail images visible
/// UseOutlines Document outline visible
/// UseThumbs Thumbnail images visible
/// UseOC Optional content group panel visible
/// This entry is meaningful only if the value of the PageMode entry in the catalog
/// dictionary is FullScreen; it is ignored otherwise. Default value: UseNone.
/// </summary>
[KeyInfo(KeyType.Name | KeyType.Optional)]
public const string NonFullScreenPageMode = "/NonFullScreenPageMode";
/// <summary>
/// (Optional; PDF 1.3) The predominant reading order for text:
/// L2R Left to right
/// R2L Right to left (including vertical writing systems, such as Chinese, Japanese, and Korean)
/// This entry has no direct effect on the document<6E>s contents or page numbering
/// but can be used to determine the relative positioning of pages when displayed
/// side by side or printed n-up. Default value: L2R.
/// </summary>
[KeyInfo(KeyType.Name | KeyType.Optional)]
public const string Direction = "/Direction";
/// <summary>
/// (Optional; PDF 1.4) The name of the page boundary representing the area of a page
/// to be displayed when viewing the document on the screen. The value is the key
/// designating the relevant page boundary in the page object. If the specified page
/// boundary is not defined in the page object, its default value is used.
/// Default value: CropBox.
/// Note: This entry is intended primarily for use by prepress applications that
/// interpret or manipulate the page boundaries as described in Section 10.10.1, <20>Page Boundaries.<2E>
/// Most PDF consumer applications disregard it.
/// </summary>
[KeyInfo(KeyType.Name | KeyType.Optional)]
public const string ViewArea = "/ViewArea";
/// <summary>
/// (Optional; PDF 1.4) The name of the page boundary to which the contents of a page
/// are to be clipped when viewing the document on the screen. The value is the key
/// designating the relevant page boundary in the page object. If the specified page
/// boundary is not defined in the page object, its default value is used.
/// Default value: CropBox.
/// Note: This entry is intended primarily for use by prepress applications that
/// interpret or manipulate the page boundaries as described in Section 10.10.1, <20>Page Boundaries.<2E>
/// Most PDF consumer applications disregard it.
/// </summary>
[KeyInfo(KeyType.Name | KeyType.Optional)]
public const string ViewClip = "/ViewClip";
/// <summary>
/// (Optional; PDF 1.4) The name of the page boundary representing the area of a page
/// to be rendered when printing the document. The value is the key designating the
/// relevant page boundary in the page object. If the specified page boundary is not
/// defined in the page object, its default value is used.
/// Default value: CropBox.
/// Note: This entry is intended primarily for use by prepress applications that
/// interpret or manipulate the page boundaries as described in Section 10.10.1, <20>Page Boundaries.<2E>
/// Most PDF consumer applications disregard it.
/// </summary>
[KeyInfo(KeyType.Name | KeyType.Optional)]
public const string PrintArea = "/PrintArea";
/// <summary>
/// (Optional; PDF 1.4) The name of the page boundary to which the contents of a page
/// are to be clipped when printing the document. The value is the key designating the
/// relevant page boundary in the page object. If the specified page boundary is not
/// defined in the page object, its default value is used.
/// Default value: CropBox.
/// Note: This entry is intended primarily for use by prepress applications that interpret
/// or manipulate the page boundaries. Most PDF consumer applications disregard it.
/// </summary>
[KeyInfo(KeyType.Name | KeyType.Optional)]
public const string PrintClip = "/PrintClip";
/// <summary>
/// (Optional; PDF 1.6) The page scaling option to be selected when a print dialog is
/// displayed for this document. Valid values are None, which indicates that the print
/// dialog should reflect no page scaling, and AppDefault, which indicates that
/// applications should use the current print scaling. If this entry has an unrecognized
/// value, applications should use the current print scaling.
/// Default value: AppDefault.
/// Note: If the print dialog is suppressed and its parameters are provided directly
/// by the application, the value of this entry should still be used.
/// </summary>
[KeyInfo(KeyType.Name | KeyType.Optional)]
public const string PrintScaling = "/PrintScaling";
/// <summary>
/// Gets the KeysMeta for these keys.
/// </summary>
public static DictionaryMeta Meta
{
get { return _meta ?? (_meta = CreateMeta(typeof(Keys))); }
}
static DictionaryMeta _meta;
}
/// <summary>
/// Gets the KeysMeta of this dictionary type.
/// </summary>
internal override DictionaryMeta Meta
{
get { return Keys.Meta; }
}
}
}

116
PdfSharp/Pdf/TrimMargins.cs Normal file
View File

@@ -0,0 +1,116 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System.Diagnostics;
using PdfSharp.Drawing;
namespace PdfSharp.Pdf
{
/// <summary>
/// Represents trim margins added to the page.
/// </summary>
[DebuggerDisplay("(Left={_left.Millimeter}mm, Right={_right.Millimeter}mm, Top={_top.Millimeter}mm, Bottom={_bottom.Millimeter}mm)")]
public sealed class TrimMargins
{
///// <summary>
///// Clones this instance.
///// </summary>
//public TrimMargins Clone()
//{
// TrimMargins trimMargins = new TrimMargins();
// trimMargins.left = left;
// trimMargins.top = top;
// trimMargins.right = right;
// trimMargins.bottom = bottom;
// return trimMargins;
//}
/// <summary>
/// Sets all four crop margins simultaneously.
/// </summary>
public XUnit All
{
set
{
_left = value;
_right = value;
_top = value;
_bottom = value;
}
}
/// <summary>
/// Gets or sets the left crop margin.
/// </summary>
public XUnit Left
{
get { return _left; }
set { _left = value; }
}
XUnit _left;
/// <summary>
/// Gets or sets the right crop margin.
/// </summary>
public XUnit Right
{
get { return _right; }
set { _right = value; }
}
XUnit _right;
/// <summary>
/// Gets or sets the top crop margin.
/// </summary>
public XUnit Top
{
get { return _top; }
set { _top = value; }
}
XUnit _top;
/// <summary>
/// Gets or sets the bottom crop margin.
/// </summary>
public XUnit Bottom
{
get { return _bottom; }
set { _bottom = value; }
}
XUnit _bottom;
/// <summary>
/// Gets a value indicating whether this instance has at least one margin with a value other than zero.
/// </summary>
public bool AreSet
{
get { return _left.Value != 0 || _right.Value != 0 || _top.Value != 0 || _bottom.Value != 0; }
}
}
}

View File

@@ -0,0 +1,55 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
namespace PdfSharp.Pdf
{
/// <summary>
/// Identifies the state of the document
/// </summary>
[Flags]
enum DocumentState
{
/// <summary>
/// The document was created from scratch.
/// </summary>
Created = 0x0001,
/// <summary>
/// The document was created by opening an existing PDF file.
/// </summary>
Imported = 0x0002,
/// <summary>
/// The document is disposed.
/// </summary>
Disposed = 0x8000,
}
}

View File

@@ -0,0 +1,52 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
namespace PdfSharp.Pdf
{
/// <summary>
/// Specifies what color model is used in a PDF document.
/// </summary>
public enum PdfColorMode
{
/// <summary>
/// All color values are written as specified in the XColor objects they come from.
/// </summary>
Undefined,
/// <summary>
/// All colors are converted to RGB.
/// </summary>
Rgb,
/// <summary>
/// All colors are converted to CMYK.
/// </summary>
Cmyk,
}
}

View File

@@ -0,0 +1,52 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
namespace PdfSharp.Pdf
{
/// <summary>
/// This class is undocumented and may change or drop in future releases.
/// </summary>
public enum PdfCustomValueCompressionMode
{
/// <summary>
/// Use document default to determine compression.
/// </summary>
Default,
/// <summary>
/// Leave custom values uncompressed.
/// </summary>
Uncompressed,
/// <summary>
/// Compress custom values using FlateDecode.
/// </summary>
Compressed,
}
}

View File

@@ -0,0 +1,52 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
namespace PdfSharp.Pdf
{
/// <summary>
/// Sets the mode for the Deflater (FlateEncoder).
/// </summary>
public enum PdfFlateEncodeMode
{
/// <summary>
/// The default mode.
/// </summary>
Default,
/// <summary>
/// Fast encoding, but larger PDF files.
/// </summary>
BestSpeed,
/// <summary>
/// Best compression, but takes more time.
/// </summary>
BestCompression,
}
}

View File

@@ -0,0 +1,63 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
namespace PdfSharp.Pdf
{
/// <summary>
/// Specifies the embedding options of an XFont when converted into PDF.
/// Font embedding is not optional anymore. So Always is the only option.
/// </summary>
public enum PdfFontEmbedding
{
/// <summary>
/// All fonts are embedded.
/// </summary>
Always,
/// <summary>
/// Fonts are not embedded. This is not an option anymore.
/// </summary>
[Obsolete("Fonts must always be embedded.")]
None,
/// <summary>
/// Unicode fonts are embedded, WinAnsi fonts are not embedded.
/// </summary>
[Obsolete("Fonts must always be embedded.")]
Default,
/// <summary>
/// Not yet implemented.
/// </summary>
[Obsolete("Fonts must always be embedded.")]
Automatic,
}
}

View File

@@ -0,0 +1,68 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
using System;
namespace PdfSharp.Pdf
{
/// <summary>
/// Specifies the encoding schema used for an XFont when converted into PDF.
/// </summary>
public enum PdfFontEncoding
{
// TABLE
/// <summary>
/// Cause a font to use Windows-1252 encoding to encode text rendered with this font.
/// Same as Windows1252 encoding.
/// </summary>
WinAnsi = 0,
///// <summary>
///// Cause a font to use Windows-1252 (aka WinAnsi) encoding to encode text rendered with this font.
///// </summary>
//Windows1252 = 0,
/// <summary>
/// Cause a font to use Unicode encoding to encode text rendered with this font.
/// </summary>
Unicode = 1,
/// <summary>
/// Unicode encoding.
/// </summary>
[Obsolete("Use WinAnsi or Unicode")]
Automatic = 1, // Force Unicode when used.
// Implementation note: PdfFontEncoding uses incorrect terms.
// WinAnsi correspond to WinAnsiEncoding, while Unicode uses glyph indices.
// Furthermre the term WinAnsi is an oxymoron.
// Reference: TABLE D.1 Latin-text encodings / Page 996
}
}

View File

@@ -0,0 +1,62 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
// Review: OK - StL/14-10-05
using System;
namespace PdfSharp.Pdf
{
/// <summary>
/// Specifies the font style for the outline (bookmark) text.
/// </summary>
[Flags]
public enum PdfOutlineStyle // Reference: TABLE 8.5 Ouline Item flags / Page 587
{
/// <summary>
/// Outline text is displayed using a regular font.
/// </summary>
Regular = 0,
/// <summary>
/// Outline text is displayed using an italic font.
/// </summary>
Italic = 1,
/// <summary>
/// Outline text is displayed using a bold font.
/// </summary>
Bold = 2,
/// <summary>
/// Outline text is displayed using a bold and italic font.
/// </summary>
BoldItalic = 3,
}
}

View File

@@ -0,0 +1,98 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
// ReSharper disable InconsistentNaming because we use PDF names.
namespace PdfSharp.Pdf
{
/// <summary>
/// Specifies the type of a page destination in outline items, annotations, or actions..
/// </summary>
public enum PdfPageDestinationType // Reference: TABLE 8.2 Destination Syntax / Page 582
{
// Except for FitR the documentation text is outdated.
/// <summary>
/// Display the page with the coordinates (left, top) positioned at the upper-left corner of
/// the window and the contents of the page magnified by the factor zoom.
/// </summary>
Xyz,
/// <summary>
/// Display the page with its contents magnified just enough to fit the
/// entire page within the window both horizontally and vertically.
/// </summary>
Fit,
/// <summary>
/// Display the page with the vertical coordinate top positioned at the top edge of
/// the window and the contents of the page magnified just enough to fit the entire
/// width of the page within the window.
/// </summary>
FitH,
/// <summary>
/// Display the page with the horizontal coordinate left positioned at the left edge of
/// the window and the contents of the page magnified just enough to fit the entire
/// height of the page within the window.
/// </summary>
FitV,
/// <summary>
/// Display the page designated by page, with its contents magnified just enough to
/// fit the rectangle specified by the coordinates left, bottom, right, and topentirely
/// within the window both horizontally and vertically. If the required horizontal and
/// vertical magnification factors are different, use the smaller of the two, centering
/// the rectangle within the window in the other dimension. A null value for any of
/// the parameters may result in unpredictable behavior.
/// </summary>
FitR,
/// <summary>
/// Display the page with its contents magnified just enough to fit the rectangle specified
/// by the coordinates left, bottom, right, and topentirely within the window both
/// horizontally and vertically.
/// </summary>
FitB,
/// <summary>
/// Display the page with the vertical coordinate top positioned at the top edge of
/// the window and the contents of the page magnified just enough to fit the entire
/// width of its bounding box within the window.
/// </summary>
FitBH,
/// <summary>
/// Display the page with the horizontal coordinate left positioned at the left edge of
/// the window and the contents of the page magnified just enough to fit the entire
/// height of its bounding box within the window.
/// </summary>
FitBV,
}
}

View File

@@ -0,0 +1,67 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
namespace PdfSharp.Pdf
{
/// <summary>
/// Specifies the page layout to be used by a viewer when the document is opened.
/// </summary>
public enum PdfPageLayout
{
/// <summary>
/// Display one page at a time.
/// </summary>
SinglePage,
/// <summary>
/// Display the pages in one column.
/// </summary>
OneColumn,
/// <summary>
/// Display the pages in two columns, with oddnumbered pages on the left.
/// </summary>
TwoColumnLeft,
/// <summary>
/// Display the pages in two columns, with oddnumbered pages on the right.
/// </summary>
TwoColumnRight,
/// <summary>
/// (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the left.
/// </summary>
TwoPageLeft,
/// <summary>
/// (PDF 1.5) Display the pages two at a time, with odd-numbered pages on the right.
/// </summary>
TwoPageRight,
}
}

View File

@@ -0,0 +1,69 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
// ReSharper disable InconsistentNaming
namespace PdfSharp.Pdf
{
/// <summary>
/// Specifies how the document should be displayed by a viewer when opened.
/// </summary>
public enum PdfPageMode
{
/// <summary>
/// Neither document outline nor thumbnail images visible.
/// </summary>
UseNone,
/// <summary>
/// Document outline visible.
/// </summary>
UseOutlines,
/// <summary>
/// Thumbnail images visible.
/// </summary>
UseThumbs,
/// <summary>
/// Full-screen mode, with no menu bar, windowcontrols, or any other window visible.
/// </summary>
FullScreen,
/// <summary>
/// (PDF 1.5) Optional content group panel visible.
/// </summary>
UseOC,
/// <summary>
/// (PDF 1.6) Attachments panel visible.
/// </summary>
UseAttachments,
}
}

View File

@@ -0,0 +1,47 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
namespace PdfSharp.Pdf
{
/// <summary>
/// Specifies how the document should be displayed by a viewer when opened.
/// </summary>
public enum PdfReadingDirection
{
/// <summary>
/// Left to right.
/// </summary>
LeftToRight,
/// <summary>
/// Right to left (including vertical writing systems, such as Chinese, Japanese, and Korean)
/// </summary>
RightToLeft,
}
}

View File

@@ -0,0 +1,50 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
// ReSharper disable InconsistentNaming
namespace PdfSharp.Pdf
{
/// <summary>
/// Specifies how text strings are encoded. A text string is any text used outside of a page content
/// stream, e.g. document information, outline text, annotation text etc.
/// </summary>
public enum PdfTextStringEncoding
{
/// <summary>
/// Specifies that hypertext uses PDF DocEncoding.
/// </summary>
PDFDocEncoding = 0,
/// <summary>
/// Specifies that hypertext uses unicode encoding.
/// </summary>
Unicode = 1,
}
}

View File

@@ -0,0 +1,55 @@
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
// Stefan Lange
//
// Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany)
//
// http://www.pdfsharp.com
// http://sourceforge.net/projects/pdfsharp
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion
namespace PdfSharp.Pdf
{
/// <summary>
/// Specifies whether to compress JPEG images with the FlateDecode filter.
/// </summary>
public enum PdfUseFlateDecoderForJpegImages
{
/// <summary>
/// PDFsharp will try FlateDecode and use it if it leads to a reduction in PDF file size.
/// When FlateEncodeMode is set to BestCompression, this is more likely to reduce the file size,
/// but it takes considerably more time to create the PDF file.
/// </summary>
Automatic,
/// <summary>
/// PDFsharp will never use FlateDecode - files may be a few bytes larger, but file creation is faster.
/// </summary>
Never,
/// <summary>
/// PDFsharp will always use FlateDecode, even if this leads to larger files;
/// this option is meant for testing purposes only and should not be used for production code.
/// </summary>
Always,
}
}