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;
}