[Solved] Printing with high DPI values

The PDF Creator .NET Library enables you to create secure PDF documents on the fly and to view, print and process existing PDF documents. If you have any questions about PDF Creator .Net, please post them here.
Post Reply
floele
Posts: 8
Joined: Wed Nov 14 2007

[Solved] Printing with high DPI values

Post by floele »

Hi.

I'm currently using the PDF Creator to print into a device context given to me by a different component in our application. It became apparent that it is necessary to increase the zoom level for higher DPI values. Currently, it is calculated like this:

Code: Select all

Graphics grDpi = Graphics.FromHdc(new System.IntPtr(hdc));
int zoom = (int)(144 * (grDpi.DpiX / 100.0f) * m_Zoom);
m_PdfDoc.ZoomFactor = zoom;
...
m_PdfDoc.DrawCurrentPage((int)hdc, true);
Unfortunately, if the DPI value is very high (like 1800), the zoom level is much higher than your library supports and thus the document is printed smaller than expected (in our case it only fills a quarter of the page).
What can be done to solve this problem?

Regards,
Florian
Jose
Amyuni Team
Posts: 553
Joined: Tue Oct 01 2002
Contact:

Post by Jose »

Hello,

It seens that you are missing a couple of lines to set the scaling factor on the destination device context (the device context that the PDFCreator will draw to.)

Now in .Net these two methods are not exposed directly, you will need to import them this way:

[DllImport("gdi32.dll")]
public static extern int SaveDC(int hdc);

[DllImport("gdi32.dll")]
public static extern bool RestoreDC(int hdc, int nSavedDC);

[DllImport("gdi32.dll")]
public static extern int SetMapMode(int hdc, int fnMapMode);

[DllImport("gdi32.dll")]
public static extern bool SetWindowExtEx(int hdc, int nXExtent, int nYExtent, out Size size);

[DllImport("gdi32.dll")]
public static extern bool SetViewportExtEx(int hdc, int nXExtent, int nYExtent, out Size size);


then the following pseudo-code snippet or something similar should do the job:

{
IntPtr hdc = g.GetHdc(); //get the device context from the Graphics object
int hMemDC = hdc.ToInt32();
int saveDC;
int oldMap;

Size oldWindow, oldView;

// save current dc
saveDC = SaveDC( hMemDC );

// set scale and origin
oldMap = SetMapMode( hMemDC, 7 ); // #define MM_ISOTROPIC 7

// set scaling factor
SetWindowExtEx( hMemDC, 2000, 2000, out oldWindow );
SetViewportExtEx( hMemDC, zoomFactor, zoomFactor, out oldView );

pdf.DrawCurrentPage( hdc, false ); //draw the page

// reset previous scaling
SetViewportExtEx( hMemDC, oldView.Width, oldView.Height, out oldView );
SetWindowExtEx( hMemDC, oldWindow.Width, oldWindow.Height, out oldWindow );
SetMapMode( hMemDC, oldMap );
RestoreDC( hMemDC, saveDC );

g.ReleaseHdc( hdc );
}


Hope this helps?
floele
Posts: 8
Joined: Wed Nov 14 2007

Post by floele »

Thanks, that was the right hint. It took quite a while though to figure out the full code:

Code: Select all

int saveDC;
int oldMap;

Size oldWindow, oldView;

// save current dc
saveDC = SaveDC( hMemDC );

// set scale and origin
oldMap = SetMapMode( hMemDC, 7 ); // #define MM_ISOTROPIC 7

int dvPxX = GetDeviceCaps(hMemDC, PHYSICALWIDTH); // 110
int dvPxY = GetDeviceCaps(hMemDC, PHYSICALHEIGHT); // 111

SetWindowExtEx( hMemDC, m_PdfDoc.GetPageFormat().Width, m_PdfDoc.GetPageFormat().Length, out oldWindow );
SetViewportExtEx( hMemDC, dvPxX, dvPxY, out oldView );

m_PdfDoc.DrawCurrentPage((int)hMemDC, false);

// reset previous scaling
SetViewportExtEx( hMemDC, oldView.Width, oldView.Height, out oldView );
SetWindowExtEx( hMemDC, oldWindow.Width, oldWindow.Height, out oldWindow );
SetMapMode( hMemDC, oldMap );
RestoreDC( hMemDC, saveDC );
Post Reply