Steps to upgrade to PDFNet SDK v.4

Steps to upgrade to PDFNet SDK v.4.

For the most up-to-date version of this document, please see

  1. Download the latest SDK from http://www.pdftron.com/downloads.html
    and extract
    the archive to any location (e.g. to C:/PDFNet).

  2. Update your project solution to use the new library:
    [.NET Specifics] Remove the old reference to PDFNet11.DLL and add a
    new reference
    to PDFNet.DLL. Please note that the DLL is renamed from PDFNet11 to
    PDFNet.

[C/C++ Specifics] Add a path to ‘C:/PDFNet/Headers’ to your project
‘include’
directories. Replace the previous PDFNet link dependency (‘Linker /
Input /
Additional Dependencies’) with a reference to ‘C:/PDFNet/Lib/
PDFNetC.lib’.
To simplify development you may want to copy the DLL to ‘Windows32’
folder or to
some other location that is included in your application’s DLL
search path. When
you are deploying the application you will most likely want to
include PDFNetC.DLL
in your application’s executable folder.

  1. Instruct the library to run in the production mode by passing the
    most up-to-date
    license key in the call to PDFNet.Initialize("…my license
    key…"). If the
    license key is not specified, the library will run in the demo
    mode. If the
    license key is not valid, PDFNet.Initialize("") will throw an
    exception (in this case you may need to obtain the new license key
    from in…@pdftron.com).

  2. Resolve the compilation errors.
    The compilation errors will fall in one of the following
    categories:

A) Simple name changes.
For example, PDFDoc.GetPagesCout() should be replaced with
GetPageCount().
A listing of symbol changes can be found on ‘What’s New’ page:

B) Changes in the Iterator interface (e.g. used to traverse pages
of fields).
Prior to PDFNet v4, a ‘for’ loop used to traverse all pages in
the document
may look as follows:

PageIterator itr = pdfdoc.PageBegin();
PageIterator end = pdfdoc.PageEnd();
for (; itr!=end; itr.Next()) {
Page pg = itr.Current();
}

PDFNet v4 loop would look as follows:

for (PageIterator = pdfdoc.GetPageIterator(); itr.HasNext();
itr.Next()) {
Page pg = itr.Current();
}

The following code snippet used to fetch the first and fifth
page:

Page first_page = pdfdoc.PageBegin().Current();
Page fifth_page = pdfdoc.PageFind(5).Current();

can be rewritten as follows:

Page first_page = pdfdoc.GetPage(1); // or
pdfdoc.GetPageIterator().Current();
Page fifth_page = pdfdoc.GetPage(5);
if (fifth_page != null) …

Similarly a code snippet used to traverse all form-fields in a
PDF/FDF document
would look as follows:

’ Assuming VB.Net:
Dim itr As FieldIterator = doc.GetFieldIterator()
While itr.HasNext()
Console.WriteLine(“Field name: {0:s}”,
itr.Current().GetName())
itr.Next()
End While

C) Changes in the low-level SDF/Cos API. The SDF/Cos API is
refactored to simplify
coding and thus reduce errors during development. The updated
API is the same
in all programming languages, which also simplifies porting code
from one
language to another. Finally, the new SDF/Cos architecture will
allow PDFNet SDK
to deliver further performance improvements in upcoming PDFNet v.
4.x releases.

For example, the following code snippet used to create a text
annotation using
the SDF API:

Obj text_annot = doc.CreateDict();
text_annot.Put(“Subtype”, doc.CreateName(“Text”));
text_annot.Put(“Open”, doc.CreateBool(true));
text_annot.Put(“Contents”, doc.CreateString(“The quick brown fox
ate the lazy mouse.”));
text_annot.Put(“Rect”, Rect.CreateSDFRect(266, 116, 430, 204));
annot_array.PushBack(text_annot);

can be corrected as fllows:

Obj text_annot = annot_array.PushBackArray();
text_annot.PutName(“Subtype”, “Text”);
text_annot.PutBool(“Open”, true);
text_annot.PutString(“Contents”, “The quick brown fox ate the
lazy mouse.”);
text_annot.PutRect(“Rect”, 266, 116, 430, 204);

For more examples illustrating the use of updated SDF/Cos API,
you may want
take a look at SDF and Annotation sample projects.

D) In case you were passing Obj ‘hints’ in the call to
pdftron.PDF.Image.CreateImage()
or pdftron.PDF.PDFDraw.Export(), please make the following
adjustment:

// Note: The only difference is that mono and gray hint are
created in
// ObjSet instead of using Obj.Create
ObjSet hint_set=new ObjSet(); // A collection of rendering
‘hits’.

// Initialize render ‘gray_hint’ parameter, that is used to
control the
// rendering process. In this case we tell the rasterizer to
export the image
// as 1 Bit Per Component (BPC) image.
Obj mono_hint=hint_set.CreateDict();
mono_hint.PutNumber(“BPC”, 1);
draw.Export(page, “mono.tif”, “TIF”, mono_hint);

// ‘gray_hint’ tells the rasterizer to export the image as
grayscale.
Obj gray_hint=hint_set.CreateDict();
gray_hint.PutName(“ColorSpace”, “Gray”);
draw.Export(page, “gray.png”, “PNG”, gray_hint);


Q: I'm wondering what impact the design choices (related to updated
Cos/SDF API and compiler independent DLL) might have on performace?
----
A: There are many reasons to update the Cos/SDF API and we were
delaying this change for some time. The change will allow users to
have a consistent API across all supported languages and platforms,
but most importantly it will allow us to speed up parsing and
rendering in future PDFNet updates (through custom memory allocators
etc).

In terms of raw performance, PDFNet v4.0 is the same as v.3.7.x,
however future versions of PDFNet will be significantly faster than v.
3.7.

Q: If I do Obj.Find to get an iterator, it's not very intuitive to
call HasNext() on that iterator to check if I found my object. Maybe
an operator bool would fit nicely?
---
A:

To make your code clear you may want to use Obj.FindObj() instead of
Obj.Find(). For example:

Obj obj = mydict.FindObj("MyKey");
if (obj != null) return;
... use obj

Q: I am in the process of converting our app to the new v4.0 API. I'm
not sure what the appropriate replacement for the following line of
code is:

fontDescriptor.Replace(dictIterator, Obj.CreateName(fontName));

- where fontDescroptor is of type Obj.

I can't find any usage of Replace in the old sample projects to
compare to the new ones.
----
A:

Use: fontDescriptor.PutName(dictIterator.Key(), fontName);

Q: I've a function that downsamples a PDF. Generally, this function
just walks through all the objects and ignores everything except
images. Images get converted and then the original image gets swapped
out with the new one.

I don't quite understand how hints have changed in PDFNet v4

' What ORIGINALLY WAS...
hntEncoder.PushBack(obj.CreateName("JPEG"))
hntEncoder.PushBack(obj.CreateName("Quality"))
hntEncoder.PushBack(obj.CreateNumber(intJPEGQuality))

'I think now it might be...
_JBIG2_hint.GetAt(1).SetName("JPEG")
_JBIG2_hint.GetAt(2).SetName("Quality")
_JBIG2_hint.GetAt(3).SetNumber(intJPEGQuality)

'Or is it...
_JBIG2_hint.PushBackName("JPEG")
_JBIG2_hint.PushBackName("Quality")
_JBIG2_hint.PushBackNumber(intJPEGQuality)

Is it documented anywhere exactly how to use hints?
-------
A: The correct conversion is the second code snippet:
_JBIG2_hint.PushBackName("JPEG")
_JBIG2_hint.PushBackName("Quality")
_JBIG2_hint.PushBackNumber(intJPEGQuality)

You can find more about changes related to PDFNet v4 using the
following link:

Q: I was trying to implement the code.
I have added PDFNET.dll to the references.

But most of the methods are not found,
Like
   // Set the bounding box
   stm.Put("BBox", Rect.CreateSDFRect(bbox));
   stm.Put("Subtype", Obj.CreateName("Form"));

it says Rect.CreateSDFRect,Obj.CreateName doesn’t contain the
definition

What will be the problem?
Is there any other dll related with it so that I need to add to
references.
------
A:

I assume that you are using the latest PDFNet DLL. There were minor
changes in the low-level starting with v4.0 (for more info, please see
http://www.pdftron.com/net/pdfnet4_upgrade.txt).

PDFNet v4 equivalent of your code snippet is:

stm.PutRect("BBox", bbox.x1, bbox.y1, bbox.x2, bbox.y2);
stm.PutName("Subtype", "Form");

Q: I found this in your porting guide:

Changes in the Iterator interface (e.g. used to traverse pages of
fields).
Prior to PDFNet v4, a 'for' loop used to traverse all pages in the
document
may look as follows

PageIterator itr = pdfdoc.PageBegin();
PageIterator end = pdfdoc.PageEnd();
for (; itr!=end; itr.Next()) {
Page pg = itr.Current();
}

PDFNet v4 loop would look as follows:

for (PageIterator = pdfdoc.GetPageIterator(); itr.HasNext();
itr.Next()) {
  Page pg = itr.Current();
}

The part that puzzles me is the itr.HasNext() condition. When itr
points to the last page, there is no "next page", so intuitively
itr.HasNext() should return FALSE, so the loop will never visit the
last page.

Is seems that there is some logic flaw here. Could be because of
unfortunate choice of the name for "HasNext()" method. Could be
because the sample code is wrong. Or like I said... Could be because
I'm puzzled.
---------
A: You are right. If 'itr' points to the last page itr.HasNext()
should return FALSE.
Under the hood 'itr.HasNext()' is equivalent to 'itr!
=pdfdoc.PageEnd()'.

I guess the only weird case would be if a PDF document didn't contain
any pages (which is btw. never the case). In this case 'itr.HasNext()'
would also return false, even though itr itself is not defined (i.e.
itr==pdfdoc.PageEnd()).

It is true that STL iterators are more intuitive, however starting
with version v.4 we wanted to unify different PDFNet APIs (.NET, JAVA,
C/C++, etc), to simplify interfaces, and remove all dependencies on
STL. We looked at both JAVA iterators and .NET enumerators and to our
surprise found them even less intuitive.