0

In C#, .NET 3.5 with winforms I am working on a print preview control. It seems to work fine, but when I print an A4 page I scanned in at real size on an A3 page, teh scale is out by about 3%...

I am using the following code to compute the actual printable area of the page based on the setting selected by the user and I am wondering if I maybe got those calculations wrong?

public static RectangleF GetPrintArea(PageSettings PageSettings)
    {
        float[] margins;
        RectangleF printArea;

        // Get the actual page bounds
        printArea = PageSettings.Bounds;

        // Calculate the hard margins taking into account page orientation
        margins = new float[4];
        // Left
        margins[0] = !PageSettings.Landscape ? PageSettings.HardMarginX : PageSettings.HardMarginY;
        // Top
        margins[1] = !PageSettings.Landscape ? PageSettings.HardMarginY : PageSettings.HardMarginX;
        // Right
        margins[2] = margins[0];
        // Bottom
        margins[3] = margins[1];

        // Calculate the real print margins taking into account teh hard and soft margins
        // left
        margins[0] = Math.Max(margins[0], PageSettings.Margins.Left);
        // Top
        margins[1] = Math.Max(margins[1], PageSettings.Margins.Top);
        // Right
        margins[2] = Math.Max(margins[2], PageSettings.Margins.Right);
        // Bottom
        margins[3] = Math.Max(margins[3], PageSettings.Margins.Bottom);

        return new RectangleF(
            new PointF(margins[0], margins[1]),
            new SizeF(printArea.Width - (margins[0] + margins[2]), printArea.Height - (margins[1] + margins[3]))
         );
    }

This should return a rectangle which gives the actual area of the page on printing will happen. I use this rectangle for generating both the preview and the printout.

The code for printing out is as follows:

    /// <summary>
    /// Draws the image on the printing surface
    /// </summary>
    /// <param name="Graphics">The graohics object with which to draw</param>
    protected virtual void PrintImage(Graphics Graphics)
    {
        RectangleF imageBoundingBox;
        RectangleF visibleImageBoundingBox;
        RectangleF visibleImage;

        // Offset the visible bounding box location by the position of the print area so as to print right within the margins
        Graphics.TranslateTransform(-this.Page.PrintableArea.Left, -this.Page.PrintableArea.Top);

        // Calculate the bounding box of the scaled image
        imageBoundingBox = new RectangleF(this.Page.PrintAreaOrigin.Add(this.ImagePrintLocation), this.Image.Size.Multiply(this.ImagePrintScale));

        // Calculate the position and size of the portion of the image bounding box visible in the viewport
        visibleImageBoundingBox = RectangleF.Intersect(imageBoundingBox, this.Page.PrintArea);

        // Calculate the portion of the image which corresponds to the visible bounding box
        visibleImage = new RectangleF(
            new PointF(
                imageBoundingBox.X < this.Page.PrintArea.Left ? Math.Min(this.Page.PrintArea.Left - imageBoundingBox.X, imageBoundingBox.Width) : 0,
                imageBoundingBox.Y < this.Page.PrintArea.Top ? Math.Min(this.Page.PrintArea.Top - imageBoundingBox.Y, imageBoundingBox.Height) : 0
            ).Divide(this.ImagePrintScale),
            visibleImageBoundingBox.Size.Divide(this.ImagePrintScale)
        );

        // Draw the image
        Graphics.DrawImage(this.Image, visibleImageBoundingBox, visibleImage, GraphicsUnit.Pixel);
    }

Where Page is a class which contains the page bounds (PageArea), the printable area PrintableArea and the actual print area (PrintArea). The actual print area is the area which is given by the previous rectangle.

Something must be wrong with this approach, but I can't for the life of me figure out what it is. If anybody can identify what's wrong I would be very grateful...

yu_ominae
  • 2,975
  • 6
  • 39
  • 76
  • why dont you use printdocument control with the printpage event,the printpageeventargs has all those settings. – terrybozzio Jun 25 '13 at 00:39
  • I do use that. That's where the Graphics object comes from. But this is for a graphic preview interface and as far as I know I cannot get the actual page bounds from the `printdocument` without firing an actual print event... – yu_ominae Jun 25 '13 at 00:57
  • take a look at this it might help http://stackoverflow.com/questions/8761633/how-to-find-the-actual-printable-area-printdocument – terrybozzio Jun 25 '13 at 01:37
  • Thanks, that's actually where I am coming from. Turns out that the difference is due to the printer itself... maybe it is not calibrated or I am just expecting too much accuracy from it. – yu_ominae Jun 25 '13 at 09:28

0 Answers0