Simple SDK DLL Fit PDF to paper size

PDF-XChange Viewer SDK for Developer's
(ActiveX and Simple DLL Versions)

Moderators: TrackerSupp-Daniel, Tracker Support, Vasyl-Tracker Dev Team, Chris - Tracker Supp, Sean - Tracker, Ivan - Tracker Software, Tracker Supp-Stefan

CodeWork
User
Posts: 2
Joined: Tue Feb 07, 2012 8:28 pm

Simple SDK DLL Fit PDF to paper size

Post by CodeWork »

Hello,

I currently testing your simple SDK DLL (pxcview.dll). I test it, using your C# example PXCView36. I tested the ActiveX control as well. I only need to print existing PDF documents to pre-defined printers. During my tests I got a little problem while printing the document. The document is cut at right and bottom. I set all PageSettings.Margins to zero and I try to set the PXCV_Helper.RECT pr to the PageBounds. Nothing works. I am not familiar with printing and using the GDI. While testing the ActiveX control I found an option that fits the document very well onto the paper. While creating the PDF documents I took care of the margins (non printable areas are not used). Do you have a hint for building such a "fit to paper function" within the simple SDK DLL?

I searched the board for printing topics but I could found nothing similar.

Thank you in advance
Best regards,
Daniel
Walter-Tracker Supp
User
Posts: 381
Joined: Mon Jun 13, 2011 5:10 pm

Re: Simple SDK DLL Fit PDF to paper size

Post by Walter-Tracker Supp »

Hi Daniel,

When you render the PDF document to the printer Device Context, with PXCV_DrawPagetoDC(), you must specify both the whole page rectangle and the drawing rectangle. These rectangles are members of the PXV_CommonRenderParameters structure passed to that function.

If you find the page is being cropped on the top and bottom, the draw rectangle (DrawRect member) is likely smaller than the whole page rectangle. I would refer you to the PXV_CommonRenderParameters section of the viewer SDK help manual for a more detailed explanation including a graphical description of the different rectangles. The DrawRect member can function essentially as a cropped region of the page that is displayed. If you set the DrawRect pointer to NULL (or the same as the WholePageRect), the page will be drawn to fit the area specified by the RECT specified by the WholePageRect pointer, which should be the size of the page area you want the page to be fit to.

Please note that for printing it is recommended that you set Flags = pxvrpf_UseVectorRenderer, and renderTarget = pxvrm_Printing.


If this does not help, please write back and we will assist you with more detailed explanations.

Sincerely,

Walter
Tracker Support
User avatar
Ivan - Tracker Software
Site Admin
Posts: 3556
Joined: Thu Jul 08, 2004 10:36 pm
Location: Vancouver Island - Canada

Re: Simple SDK DLL Fit PDF to paper size

Post by Ivan - Tracker Software »

You have to:
1) get printer's bounding box in pixels (I don't know what language and framework you are using, so I cannot be more specific as to how to do that in your case), for example: RECT paperBox;
2) get document page size (PXCV_GetPageDimensions),for example, double pwidth, double pheight;
3) calculate the rectangle where the page should be located on the paper and print it.

Sample code:

Code: Select all

PXVDocument Doc;

RECT paperBox;
RECT printBox;
double pwidth, pheight;

// gather paperBox; you can use Windows API functions to do this; see MSDN

DWORD nPages = 0;
PXCV_GetPagesCount(Doc, &nPages);

PXV_CommonRenderParameters rparams = {0};
rparams.Flags = pxvrpf_UseVectorRenderer | pxvrpf_EmbeddedFontAsCurves;
rparams.RenderTarget = pxvrm_Printing;

printer.StartDoc();
for (DWORD i = 0; i < nPages; i++)
{
	PXCV_GetPagesCount(Doc, i, &pwidth, &pheight);
	double kw = pwidth / (double)(paperBox.right - paperBox.left);
	double kh = pheight / (double)(paperBox.bottom - paperBox.top);
        int pw, ph;
        if (kw < kh)
        {
                pw = paperBox.right - paperBox.left;
                ph = (int)((paperBox.bottom - paperBox.top) * kw);
        }
        else
        {
                ph = paperBox.bottom - paperBox.top;
                pw = (int)((paperBox.right - paperBox.left) * kh);
        }
        printBox.left = paperBox.left + (paperBox.right - paperBox.left - pw) / 2;
        printBox.right = printBox.left + pw;
        printBox.top = paperBox.top + (paperBox.bottom - paperBox.top - ph) / 2;
        printBox.bottom = printBox.top + ph;

        rparams.WholePageRect = &printBox;
        rparams.DrawRect = &printBox;

        printer.StartPage();
        PXCV_DrawPageToDC(Doc, i, printer.DC, &rparams);
        printer.EndPage();
}
printer.EndDoc();
HTH.

P.S. Please note, this topic is not specific to Simple SDK, it is general programming, and we cannot provide such help on a regular basis.
Tracker Software (Project Director)

When attaching files to any message - please ensure they are archived and posted as a .ZIP, .RAR or .7z format - or they will not be posted - thanks.
CodeWork
User
Posts: 2
Joined: Tue Feb 07, 2012 8:28 pm

Re: Simple SDK DLL Fit PDF to paper size

Post by CodeWork »

Walter, Ivan,

thanks for your very fast response. I am using C# (I am testing your C# examples coming with your simple SDK, the project is call "PXCView36"). Thanks for the code sample. I compared it with the event "OnPrintPage" in the C# sample code. It looks similar to this. I add your this example. If I understand you right, this should work. The recommende flags are used. During my tests with this code, I changed the pr.left, pr.right, pr.top, pr.bottom to the paper size (0,827,0,1169, this represents the german A4 format) PDF document has the same values. These values makes it better but the printed document is still cropped at the bottom and on the right side.

Sorry for forgetting the system details: Win7 64, MS Visual Studio 2010, Framework 2.0, Language is C#

Code: Select all

      private void OnPrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
      {
         int nPrintPageNum = m_PrintedPageCount;

         PXCV_Lib36.PXV_CommonRenderParameters crp;
         IntPtr hDC = IntPtr.Zero;
         PaperSize aPaperSize = e.PageSettings.PaperSize;
         double doc_page_w;
         double doc_page_h;

         crp.WholePageRect = IntPtr.Zero;
         crp.DrawRect = IntPtr.Zero;
         try
         {
            PXCV_Helper.RECT pr;

            m_PDFDoc.GetPageDimensions(nPrintPageNum, out doc_page_w, out doc_page_h);
            doc_page_w = doc_page_w / 72.0 * 100;                   // convert points to hundredths of an inch
            doc_page_h = doc_page_h / 72.0 * 100;                   // convert points to hundredths of an inch
            double k1 = (double)aPaperSize.Width / (double)aPaperSize.Height;
            double k2 = doc_page_w / doc_page_h;

            if (k1 < k2)
            {
               doc_page_w = Math.Min(doc_page_w, (double)aPaperSize.Width);
               doc_page_h = doc_page_w / k2;
            }
            else
            {
               doc_page_h = Math.Min(doc_page_h, (double)aPaperSize.Height);
               doc_page_w = doc_page_h * k2;
            }

            pr.left = (int)(e.PageSettings.HardMarginX + (double)aPaperSize.Width - doc_page_w) / 2;
            pr.right = pr.left + (int)doc_page_w;
            pr.top = (int)(e.PageSettings.HardMarginY + (double)aPaperSize.Height - doc_page_h) / 2;
            pr.bottom = pr.top + (int)doc_page_h;

            pr.left *= e.PageSettings.PrinterResolution.X / 100;    // convert to device units
            pr.right *= e.PageSettings.PrinterResolution.X / 100;   // convert to device units
            pr.top *= e.PageSettings.PrinterResolution.Y / 100;     // convert to device units
            pr.bottom *= e.PageSettings.PrinterResolution.Y / 100;  // convert to device units

            crp.Flags = (int)PXCV_Lib36.PXV_CommonRenderParametersFlags.pxvrpf_UseVectorRenderer;
            crp.RenderTarget = PXCV_Lib36.PXCV_RenderMode.pxvrm_Printing;
            crp.WholePageRect = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PXCV_Helper.RECT)));
            Marshal.StructureToPtr(pr, crp.WholePageRect, false);
            hDC = e.Graphics.GetHdc();
            m_PDFDoc.DrawPageToDC(hDC, nPrintPageNum, crp);
            m_PrintedPageCount++;
            e.HasMorePages = m_PrintedPageCount < m_PDFDoc.GetPagesCount();
         }
         catch (Exception)
         {
            e.HasMorePages = false;
         }
         finally
         {
            if (hDC != IntPtr.Zero)
               e.Graphics.ReleaseHdc(hDC);
            if (crp.WholePageRect != IntPtr.Zero)
               Marshal.FreeHGlobal(crp.WholePageRect);
         }
      }
Yes, this is general programming but I only try to get a hint from you. My tests with the tracker software example code are not working very well and I cannot found some more hints in the PCVwSDLL_hlp.pdf (before I open this topic).

I hope you have an idea what I have overseen or what I am doing wrong.

Best regards,
Daniel
Walter-Tracker Supp
User
Posts: 381
Joined: Mon Jun 13, 2011 5:10 pm

Re: Simple SDK DLL Fit PDF to paper size

Post by Walter-Tracker Supp »

I would recommend carefully walking through your code to calculate the whole page rectangle to ensure it is not bigger (accounting for your margins) than the paper size, as I would bet that there is an error in this calculation somewhere.

If this does not resolve it, please do respond with more details (e.g. the whole page rect bounds and the paper bounds that are actually calculated with your example on a specific test case) and we will do our best to help you resolve it.

-Walter