PDF: Low level access to the structure of PDF document
In This Topic
PDF document is represented by a tree of objects of various type.
The "tree of PDF document" (
PdfTreeNodeBase) consists from a large variety of highly specialized nodes, for example:
PdfPage - a page of PDF document,
PdfImageResource - an image resource, etc.
Each node of the tree of PDF document refers to a tree of low-level objects.
The "tree of basic objects of PDF document" consists from objects of basic types, for example: PdfName - name, PdfArray - array, etc. The
PdfBasicObject class is a base class for all objects in the tree of basic objects of PDF document.
Basic types
"The tree of basic objects of PDF document" consists from the following node types:
- PdfIntegerNumber - provides the PDF integer object that stores 32-bit signed integer number
- PdfRealNumber - provides the PDF real object that stores a floating-point number
- PdfBoolean - provides the PDF boolean object that stores boolean value
- PdfNull - provides a PDF null object
- PdfName - provides the PDF name object that stores name value
- PdfString - provides the PDF string object that stores a string value
- PdfArray - provides the PDF array object that is a one-dimensional collection of objects arranged sequentially
- PdfDictionary - Provides the PDF dictionary object that is an associative table containing pairs of (name, basic object)
- PdfStream - provides the PDF stream object that stores a sequence of bytes
- PdfIndirectObject - provides an indirect object
- PdfIndirectReference - provides a reference to indirect object
Any basic object in a PDF file may be labeled as an indirect object. This gives the object a unique object identifier (
PdfIndirectObject.Number and
PdfIndirectObject.Generation) by which other objects can refer to it use an indirect reference. All streams (
PdfStream) must be indirect objects.
The
PdfIndirectObject.GetByReference method allows to get the indirect object referred by link. The
PdfIndirectObject.GetReference method allows to get the indirect reference to the indirect object. The
PdfIndirectObject.Create method allows to create the indirect object, the identifier for the object will be assigned automatically.
Here is C#/VB.NET code that demonstrates how to create a simple PDF document using the tree of basic objects of PDF document:
/// <summary>
/// Creates a single page PDF document using only PDF basic types (basic PDF tree).
/// </summary>
/// <param name="outputPdfFilename">The output PDF filename.</param>
public static void CreatePdfDocumentUseBasicTypes(string outputPdfFilename)
{
using (Vintasoft.Imaging.Pdf.PdfDocument document =
new Vintasoft.Imaging.Pdf.PdfDocument(Vintasoft.Imaging.Pdf.PdfFormat.Pdf_14))
{
Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary catalog =
GetBasicObject<Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary>(document.Catalog.BasicObject);
Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary pages =
GetBasicObject<Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary>(catalog["Pages"]);
pages["Count"] = new Vintasoft.Imaging.Pdf.BasicTypes.PdfIntegerNumber(1);
Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary page =
new Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary(document);
pages["Kids"] = new Vintasoft.Imaging.Pdf.BasicTypes.PdfArray(document,
Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.Create(document, page).GetReference());
page["Type"] = new Vintasoft.Imaging.Pdf.BasicTypes.PdfName("Page");
page["Parent"] = catalog["Pages"];
page["MediaBox"] = new Vintasoft.Imaging.Pdf.BasicTypes.PdfArray(document,
Vintasoft.Imaging.Pdf.BasicTypes.PdfNumber.Create(0),
Vintasoft.Imaging.Pdf.BasicTypes.PdfNumber.Create(0),
Vintasoft.Imaging.Pdf.BasicTypes.PdfNumber.Create(300),
Vintasoft.Imaging.Pdf.BasicTypes.PdfNumber.Create(400));
Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary font =
new Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary(document);
font["Type"] = new Vintasoft.Imaging.Pdf.BasicTypes.PdfName("Font");
font["Subtype"] = new Vintasoft.Imaging.Pdf.BasicTypes.PdfName("Type1");
font["BaseFont"] = new Vintasoft.Imaging.Pdf.BasicTypes.PdfName("Times-Roman");
font["Encoding"] = new Vintasoft.Imaging.Pdf.BasicTypes.PdfName("WinAnsiEncoding");
Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary fontResources =
new Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary(document);
fontResources["F1"] = Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.Create(document, font).GetReference();
Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary pageResources =
new Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary(document);
pageResources["Font"] = fontResources;
page["Resources"] = pageResources;
string content = "q /F1 20 Tf BT 100 200 Td (Hello World!) Tj ET Q";
Vintasoft.Imaging.Pdf.BasicTypes.PdfStream contentStream =
new Vintasoft.Imaging.Pdf.BasicTypes.PdfStream(document);
contentStream.SetBytes(
System.Text.Encoding.ASCII.GetBytes(content),
Vintasoft.Imaging.Pdf.PdfCompression.None,
Vintasoft.Imaging.Pdf.PdfCompressionSettings.DefaultSettings);
page["Contents"] = Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.Create(document, contentStream).GetReference();
document.Save(outputPdfFilename);
}
}
/// <summary>
/// Gets the basic object of specified type.
/// </summary>
/// <typeparam name="T">Type of basic object.</typeparam>
/// <param name="obj">The basic object.</param>
private static T GetBasicObject<T>(Vintasoft.Imaging.Pdf.BasicTypes.PdfBasicObject obj)
where T : Vintasoft.Imaging.Pdf.BasicTypes.PdfBasicObject
{
if (obj is T)
return (T)obj;
if (obj is Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectReference)
return GetBasicObject<T>(
Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.GetByReference(((
Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectReference)obj)));
if (obj is Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject)
return GetBasicObject<T>(((Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject)obj).Value);
if (obj is Vintasoft.Imaging.Pdf.BasicTypes.PdfStream)
return GetBasicObject<T>(((Vintasoft.Imaging.Pdf.BasicTypes.PdfStream)obj).Dictionary);
return (T)obj;
}
''' <summary>
''' Creates a single page PDF document using only PDF basic types (basic PDF tree).
''' </summary>
''' <param name="outputPdfFilename">The output PDF filename.</param>
Public Shared Sub CreatePdfDocumentUseBasicTypes(outputPdfFilename As String)
Using document As New Vintasoft.Imaging.Pdf.PdfDocument(Vintasoft.Imaging.Pdf.PdfFormat.Pdf_14)
Dim catalog As Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary = GetBasicObject(Of Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary)(document.Catalog.BasicObject)
Dim pages As Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary = GetBasicObject(Of Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary)(catalog("Pages"))
pages("Count") = New Vintasoft.Imaging.Pdf.BasicTypes.PdfIntegerNumber(1)
Dim page As New Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary(document)
pages("Kids") = New Vintasoft.Imaging.Pdf.BasicTypes.PdfArray(document, Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.Create(document, page).GetReference())
page("Type") = New Vintasoft.Imaging.Pdf.BasicTypes.PdfName("Page")
page("Parent") = catalog("Pages")
page("MediaBox") = New Vintasoft.Imaging.Pdf.BasicTypes.PdfArray(document, Vintasoft.Imaging.Pdf.BasicTypes.PdfNumber.Create(0), Vintasoft.Imaging.Pdf.BasicTypes.PdfNumber.Create(0), Vintasoft.Imaging.Pdf.BasicTypes.PdfNumber.Create(300), Vintasoft.Imaging.Pdf.BasicTypes.PdfNumber.Create(400))
Dim font As New Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary(document)
font("Type") = New Vintasoft.Imaging.Pdf.BasicTypes.PdfName("Font")
font("Subtype") = New Vintasoft.Imaging.Pdf.BasicTypes.PdfName("Type1")
font("BaseFont") = New Vintasoft.Imaging.Pdf.BasicTypes.PdfName("Times-Roman")
font("Encoding") = New Vintasoft.Imaging.Pdf.BasicTypes.PdfName("WinAnsiEncoding")
Dim fontResources As New Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary(document)
fontResources("F1") = Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.Create(document, font).GetReference()
Dim pageResources As New Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary(document)
pageResources("Font") = fontResources
page("Resources") = pageResources
Dim content As String = "q /F1 20 Tf BT 100 200 Td (Hello World!) Tj ET Q"
Dim contentStream As New Vintasoft.Imaging.Pdf.BasicTypes.PdfStream(document)
contentStream.SetBytes(System.Text.Encoding.ASCII.GetBytes(content), Vintasoft.Imaging.Pdf.PdfCompression.None, Vintasoft.Imaging.Pdf.PdfCompressionSettings.DefaultSettings)
page("Contents") = Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.Create(document, contentStream).GetReference()
document.Save(outputPdfFilename)
End Using
End Sub
''' <summary>
''' Gets the basic object of specified type.
''' </summary>
''' <typeparam name="T">Type of basic object.</typeparam>
''' <param name="obj">The basic object.</param>
Private Shared Function GetBasicObject(Of T As Vintasoft.Imaging.Pdf.BasicTypes.PdfBasicObject)(obj As Vintasoft.Imaging.Pdf.BasicTypes.PdfBasicObject) As T
If TypeOf obj Is T Then
Return DirectCast(obj, T)
End If
If TypeOf obj Is Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectReference Then
Return GetBasicObject(Of T)(Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.GetByReference(DirectCast(obj, Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectReference)))
End If
If TypeOf obj Is Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject Then
Return GetBasicObject(Of T)(DirectCast(obj, Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject).Value)
End If
If TypeOf obj Is Vintasoft.Imaging.Pdf.BasicTypes.PdfStream Then
Return GetBasicObject(Of T)(DirectCast(obj, Vintasoft.Imaging.Pdf.BasicTypes.PdfStream).Dictionary)
End If
Return DirectCast(obj, T)
End Function
Access to basic types from PDF tree node
Each node of PDF document tree has a reference (
PdfTreeNodeBase.BasicObject) to the basic objects tree from which this node is composed. The root of the basic object tree can be accessed using
PdfTreeNodeBase.BasicObject property of the tree node
PdfDocument.Catalog.
Usually as the root of low-level tree for a node of PDF document tree acts
PdfDictionary. This structure allows to store custom user data.
Important! The changes in the tree of basic objects of PDF document are not controlled in any way. A PDF document can be corrupted if the mandatory nodes of PDF tree are changed or deleted.
Here is C#/VB.NET code that demonstrates how to add the custom data to the PDF tree nodes:
/// <summary>
/// Tests add/get custom data.
/// </summary>
public static void Test()
{
// create PDF document
using (Vintasoft.Imaging.Pdf.PdfDocument document =
new Vintasoft.Imaging.Pdf.PdfDocument("textCustomData.pdf", Vintasoft.Imaging.Pdf.PdfFormat.Pdf_14))
{
// add empty page to the PDF document
Vintasoft.Imaging.Pdf.Tree.PdfPage page = document.Pages.Add(Vintasoft.Imaging.PaperSizeKind.A4);
// add custom data to the PDF document catalog
AddCustomStringData(document.Catalog,
"MyStringData", "Test String Value 1");
AddCustomStreamData(document.Catalog,
"MyStreamData", System.Text.Encoding.Unicode.GetBytes("Test Stream Data 1"));
// add custom data to the PDF page
AddCustomStringData(page,
"MyStringData", "Test String Value 2");
AddCustomStreamData(page,
"MyStreamData", System.Text.Encoding.Unicode.GetBytes("Test Stream Data 2"));
// save changes in PDF document
document.SaveChanges();
}
// open PDF document
using (Vintasoft.Imaging.Pdf.PdfDocument document =
new Vintasoft.Imaging.Pdf.PdfDocument("textCustomData.pdf"))
{
// read "/MyStringData" entry from the PDF document catalog
System.Console.WriteLine(
GetCustomStringData(document.Catalog, "MyStringData"));
// read "/MyStreamData" entry from the PDF document catalog
System.Console.WriteLine(
System.Text.Encoding.Unicode.GetString(GetCustomStreamData(document.Catalog, "MyStreamData")));
// read "/MyStringData" entry from PDF page
System.Console.WriteLine(
GetCustomStringData(document.Pages[0], "MyStringData"));
// read "/MyStreamData" entry from PDF page
System.Console.WriteLine(
System.Text.Encoding.Unicode.GetString(GetCustomStreamData(document.Pages[0], "MyStreamData")));
}
}
/// <summary>
/// Adds the custom string data with the specified name to the specified PDF tree node.
/// </summary>
/// <param name="pdfTreeNode">The PDF tree node.</param>
/// <param name="dataName">The data name.</param>
/// <param name="dataValue">The data value.</param>
public static void AddCustomStringData(
Vintasoft.Imaging.Pdf.Tree.PdfTreeNodeBase pdfTreeNode,
string dataName,
string dataValue)
{
Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary dictionary = GetDictionary(pdfTreeNode);
if (dictionary.ContainsKey(dataName))
throw new System.ArgumentException(string.Format("Key '{0}' already exists.", dataName));
dictionary[dataName] = new Vintasoft.Imaging.Pdf.BasicTypes.PdfString(dataValue);
}
/// <summary>
/// Returns the custom string data with the specified name from the specified PDF tree node.
/// </summary>
/// <param name="pdfTreeNode">The PDF tree node.</param>
/// <param name="dataName">The data name.</param>
/// <returns>The custom string data with the specified name from the specified PDF tree node.</returns>
public static string GetCustomStringData(Vintasoft.Imaging.Pdf.Tree.PdfTreeNodeBase pdfTreeNode, string dataName)
{
Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary dictionary = GetDictionary(pdfTreeNode);
if (dictionary.ContainsKey(dataName))
return ((Vintasoft.Imaging.Pdf.BasicTypes.PdfString)dictionary[dataName]).ValueAsTextString;
throw new System.ArgumentException(string.Format("Key '{0}' is not found.", dataName));
}
/// <summary>
/// Adds the custom stream data with the specified name to the specified PDF tree node.
/// </summary>
/// <param name="pdfTreeNode">The PDF tree node.</param>
/// <param name="dataName">The data name.</param>
/// <param name="dataValue">The data value.</param>
public static void AddCustomStreamData(
Vintasoft.Imaging.Pdf.Tree.PdfTreeNodeBase pdfTreeNode,
string dataName,
byte[] dataValue)
{
Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary dictionary = GetDictionary(pdfTreeNode);
if (dictionary.ContainsKey(dataName))
throw new System.ArgumentException(string.Format("Key '{0}' already exists.", dataName));
// create a stream
Vintasoft.Imaging.Pdf.BasicTypes.PdfStream stream =
new Vintasoft.Imaging.Pdf.BasicTypes.PdfStream(pdfTreeNode.Document);
// write data, compressed with ZIP compression, to the stream
stream.SetBytes(dataValue, Vintasoft.Imaging.Pdf.PdfCompression.Zip,
Vintasoft.Imaging.Pdf.PdfCompressionSettings.DefaultSettings);
// create an indirect object from the stream
Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject indirectObject =
Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.Create(pdfTreeNode.Document, stream);
// set the reference for the specified entry
dictionary[dataName] = indirectObject.GetReference();
}
/// <summary>
/// Returns the custom stream data with specified name from specified tree node.
/// </summary>
/// <param name="pdfTreeNode">The PDF tree node.</param>
/// <param name="dataName">The data name.</param>
public static byte[] GetCustomStreamData(Vintasoft.Imaging.Pdf.Tree.PdfTreeNodeBase pdfTreeNode, string dataName)
{
Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary dictionary = GetDictionary(pdfTreeNode);
if (dictionary.ContainsKey(dataName))
{
Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectReference reference =
(Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectReference)dictionary[dataName];
Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject indirectObject =
Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.GetByReference(reference);
Vintasoft.Imaging.Pdf.BasicTypes.PdfStream stream =
(Vintasoft.Imaging.Pdf.BasicTypes.PdfStream)indirectObject.Value;
return stream.GetBytes();
}
throw new System.ArgumentException(string.Format("Key '{0}' is not found.", dataName));
}
/// <summary>
/// Returns the dictionary from PDF tree node.
/// </summary>
/// <param name="node">The node.</param>
private static Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary GetDictionary(
Vintasoft.Imaging.Pdf.Tree.PdfTreeNodeBase node)
{
Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary dictionary =
node.BasicObject as Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary;
if (dictionary == null)
throw new System.ArgumentException(
string.Format("Node {0} is not a dictionary!", node.GetType().Name));
return dictionary;
}
''' <summary>
''' Tests add/get custom data.
''' </summary>
Public Shared Sub Test()
' create PDF document
Using document As New Vintasoft.Imaging.Pdf.PdfDocument("textCustomData.pdf", Vintasoft.Imaging.Pdf.PdfFormat.Pdf_14)
' add empty page to the PDF document
Dim page As Vintasoft.Imaging.Pdf.Tree.PdfPage = document.Pages.Add(Vintasoft.Imaging.PaperSizeKind.A4)
' add custom data to the PDF document catalog
AddCustomStringData(document.Catalog, "MyStringData", "Test String Value 1")
AddCustomStreamData(document.Catalog, "MyStreamData", System.Text.Encoding.Unicode.GetBytes("Test Stream Data 1"))
' add custom data to the PDF page
AddCustomStringData(page, "MyStringData", "Test String Value 2")
AddCustomStreamData(page, "MyStreamData", System.Text.Encoding.Unicode.GetBytes("Test Stream Data 2"))
' save changes in PDF document
document.SaveChanges()
End Using
' open PDF document
Using document As New Vintasoft.Imaging.Pdf.PdfDocument("textCustomData.pdf")
' read "/MyStringData" entry from the PDF document catalog
System.Console.WriteLine(GetCustomStringData(document.Catalog, "MyStringData"))
' read "/MyStreamData" entry from the PDF document catalog
System.Console.WriteLine(System.Text.Encoding.Unicode.GetString(GetCustomStreamData(document.Catalog, "MyStreamData")))
' read "/MyStringData" entry from PDF page
System.Console.WriteLine(GetCustomStringData(document.Pages(0), "MyStringData"))
' read "/MyStreamData" entry from PDF page
System.Console.WriteLine(System.Text.Encoding.Unicode.GetString(GetCustomStreamData(document.Pages(0), "MyStreamData")))
End Using
End Sub
''' <summary>
''' Adds the custom string data with the specified name to the specified PDF tree node.
''' </summary>
''' <param name="pdfTreeNode">The PDF tree node.</param>
''' <param name="dataName">The data name.</param>
''' <param name="dataValue">The data value.</param>
Public Shared Sub AddCustomStringData(pdfTreeNode As Vintasoft.Imaging.Pdf.Tree.PdfTreeNodeBase, dataName As String, dataValue As String)
Dim dictionary As Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary = GetDictionary(pdfTreeNode)
If dictionary.ContainsKey(dataName) Then
Throw New System.ArgumentException(String.Format("Key '{0}' already exists.", dataName))
End If
dictionary(dataName) = New Vintasoft.Imaging.Pdf.BasicTypes.PdfString(dataValue)
End Sub
''' <summary>
''' Returns the custom string data with the specified name from the specified PDF tree node.
''' </summary>
''' <param name="pdfTreeNode">The PDF tree node.</param>
''' <param name="dataName">The data name.</param>
''' <returns>The custom string data with the specified name from the specified PDF tree node.</returns>
Public Shared Function GetCustomStringData(pdfTreeNode As Vintasoft.Imaging.Pdf.Tree.PdfTreeNodeBase, dataName As String) As String
Dim dictionary As Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary = GetDictionary(pdfTreeNode)
If dictionary.ContainsKey(dataName) Then
Return DirectCast(dictionary(dataName), Vintasoft.Imaging.Pdf.BasicTypes.PdfString).ValueAsTextString
End If
Throw New System.ArgumentException(String.Format("Key '{0}' is not found.", dataName))
End Function
''' <summary>
''' Adds the custom stream data with the specified name to the specified PDF tree node.
''' </summary>
''' <param name="pdfTreeNode">The PDF tree node.</param>
''' <param name="dataName">The data name.</param>
''' <param name="dataValue">The data value.</param>
Public Shared Sub AddCustomStreamData(pdfTreeNode As Vintasoft.Imaging.Pdf.Tree.PdfTreeNodeBase, dataName As String, dataValue As Byte())
Dim dictionary As Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary = GetDictionary(pdfTreeNode)
If dictionary.ContainsKey(dataName) Then
Throw New System.ArgumentException(String.Format("Key '{0}' already exists.", dataName))
End If
' create a stream
Dim stream As New Vintasoft.Imaging.Pdf.BasicTypes.PdfStream(pdfTreeNode.Document)
' write data, compressed with ZIP compression, to the stream
stream.SetBytes(dataValue, Vintasoft.Imaging.Pdf.PdfCompression.Zip, Vintasoft.Imaging.Pdf.PdfCompressionSettings.DefaultSettings)
' create an indirect object from the stream
Dim indirectObject As Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject = Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.Create(pdfTreeNode.Document, stream)
' set the reference for the specified entry
dictionary(dataName) = indirectObject.GetReference()
End Sub
''' <summary>
''' Returns the custom stream data with specified name from specified tree node.
''' </summary>
''' <param name="pdfTreeNode">The PDF tree node.</param>
''' <param name="dataName">The data name.</param>
Public Shared Function GetCustomStreamData(pdfTreeNode As Vintasoft.Imaging.Pdf.Tree.PdfTreeNodeBase, dataName As String) As Byte()
Dim dictionary As Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary = GetDictionary(pdfTreeNode)
If dictionary.ContainsKey(dataName) Then
Dim reference As Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectReference = DirectCast(dictionary(dataName), Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectReference)
Dim indirectObject As Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject = Vintasoft.Imaging.Pdf.BasicTypes.PdfIndirectObject.GetByReference(reference)
Dim stream As Vintasoft.Imaging.Pdf.BasicTypes.PdfStream = DirectCast(indirectObject.Value, Vintasoft.Imaging.Pdf.BasicTypes.PdfStream)
Return stream.GetBytes()
End If
Throw New System.ArgumentException(String.Format("Key '{0}' is not found.", dataName))
End Function
''' <summary>
''' Returns the dictionary from PDF tree node.
''' </summary>
''' <param name="node">The node.</param>
Private Shared Function GetDictionary(node As Vintasoft.Imaging.Pdf.Tree.PdfTreeNodeBase) As Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary
Dim dictionary As Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary = TryCast(node.BasicObject, Vintasoft.Imaging.Pdf.BasicTypes.PdfDictionary)
If dictionary Is Nothing Then
Throw New System.ArgumentException(String.Format("Node {0} is not a dictionary!", node.[GetType]().Name))
End If
Return dictionary
End Function