Implementing PDF print function using PDFNet.

Q: We want to print PDFs without having to use acrobat to automate the
process. Acrobat is displayed as a popup and does not always go
away. Plus it just looks clunky and is against Acrobat's license.

So I downloaded your PDFView sample from http://www.pdftron.com/net/samplecode.html
and it printed our documents perfectly. However when I look at the C#
code link that you have, I do not see the print functionality.

In addition when I look at the PDFPrint C# sample code and run it, it
does NOT render the document appropriately. There are sizing issues
and some parts are cut off. I modified the SetRasterType as document
in the sample code and also toggled the use_hard_margins feature to no
avail
-----
A: For the sample code, please refer to the code in the 'PDFNet/
Samples' folder that comes as part of the production SDK. The sample
code on the web site is used only for browsing (it does not include
all of the required files and is possibility out of date).

Regarding PDFPrint sample project there are couple of things to note:

- If the PDF page does not print properly it, means that PDFNet can't
find 'pdfnet.res' and that PDFNet.SetResourcesPath() returns false. To
resolve this problem, simply make sure that correct path is passed in
SetResourcesPath(). For more information, please see
http://www.pdftron.com/net/faq.html#pdfnet_res.

- If the print margins are not correct you may need to use different
margins (e.g. obtained using Win32 or .NET Framework API). PDFNet
offers a single method called PDFDraw.DrawInRect(...) that render the
PDF page within the given rectangle. By shifting around the rectangle
passed as a parameter in DrawInRect() you will be able to render the
PDF at the arbitrary location.

Q: I download the pdfview sample and run it - it prints correctly. I
am guessing that it is a C++ version since there is only an
executable. I am devloping under .NET and the PDFView sample is
printing the page at a slightly different offset. What can I do to
correctly position and scale the page?
----
A: pdfdraw.DrawInRect() method draws a PDF page within the given
rectangle on the output device. If the page is not printed at the
correct location, or is too small, or too large, it is very likely
that the supplied rectangle in incorrect. By changing the output
rectangle, you will be able to fit the PDF page on printed paper.

The page bounds/margins used to position the page on the output device
are typically obtained using platform specific APIs (depending on your
development environment you may use .NET Framework API, Win32 GDI,
Java APIs, etc).

To solve the problem, you may want to investigate why is the page
bound larger than expected. The code used to initialize 'rectPage'
variable is as follows:

Rectangle rectPage = ev.PageBounds; //print without margins //
Rectangle rectPage = ev.MarginBounds; //print using margins

For example, you may want to use MarginBounds instead of PageBounds.
Getting correct page bounds under .NET can be tricky, as described in
the following articles:

Useful Articles related to Printer Margins:
  Part 1: http://www.ddj.com/windows/184416821
  Part 2: http://www.ddj.com/windows/184416825

So another option is:

Rectangle rectPage = GetRealMarginBounds(PrintPageEventArgs e, bool
preview)

Where GetRealMarginBounds is defined as follows:

[System.Runtime.InteropServices.DllImport("gdi32.dll")]
private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
private const int PHYSICALOFFSETX = 112; private const int
PHYSICALOFFSETY = 113;

// Adjust MarginBounds rectangle when printing based // on the
physical characteristics of the printer static Rectangle
GetRealMarginBounds(PrintPageEventArgs e, bool preview) { if
(preview) return e.MarginBounds;

int cx = 0;
int cy = 0;
IntPtr hdc = e.Graphics.GetHdc();

try {
   // Both of these come back as device units and are not
   // scaled to 1/100th of an inch
   cx = GetDeviceCaps(hdc, PHYSICALOFFSETX);
   cy = GetDeviceCaps(hdc, PHYSICALOFFSETY); } finally {
   e.Graphics.ReleaseHdc(hdc);
}

// Create the real margin bounds by scaling the offset // by the
printer resolution and then rescaling it // back to 1/100th of an
inch
Rectangle marginBounds = e.MarginBounds;
int dpiX = (int)e.Graphics.DpiX;
int dpiY = (int)e.Graphics.DpiY;
marginBounds.Offset(-cx * 100 / dpiX, -cy * 100 / dpiY);
return marginBounds;
}