Printing a Picture

Code samples and article discussion

Moderators: Frank Hileman, Anne Szyjan

Printing a Picture

Postby Frank Hileman » Mon Mar 26, 2007 8:57 am

In the full version, use the Picture.RenderTo function to print. The Lite version has no printing support.

You will need code to initialize the transformation and clipping on the printer graphics. Here is a sample:

Printing Sample

Here is an extract from the above sample. PageSetup and Print are the entry methods:
Code: Select all
   public class PrintableCanvas : Canvas
   {
      private PrintDialog printDialog;
      private PrintDocument printDocument;
      private PageSetupDialog pageSetupDialog;

      public void PageSetup()
      {
         SetupPrintDocument();
         if (pageSetupDialog == null)
         {
            pageSetupDialog = new PageSetupDialog();
            pageSetupDialog.Document = printDocument;
         }
         pageSetupDialog.ShowDialog();
      }

      public void Print()
      {
         SetupPrintDocument();
         if (printDialog == null)
         {
            printDialog = new PrintDialog();
            printDialog.Document = printDocument;
         }
         if (printDialog.ShowDialog() != DialogResult.OK)
            return;
         printDocument.Print();
      }

      private void SetupPrintDocument()
      {
         if (printDocument == null)
         {
            printDocument = new PrintDocument();
            printDocument.PrintPage += new PrintPageEventHandler(PrintDocumentPrintPage);
         }
         // NOTE: you may use any document name instead of Picture.Name
         printDocument.DocumentName = Picture.Name;
      }

      private void PrintDocumentPrintPage(object sender, PrintPageEventArgs e)
      {
         e.HasMorePages = false;         // fit into a single page
         Graphics g = e.Graphics;
         FRectangle port;

         if (g.VisibleClipBounds.X < 0) // print preview
            port = e.MarginBounds;
         else
            port = new FRectangle(
               e.MarginBounds.Left - (e.PageBounds.Width - g.VisibleClipBounds.Width) / 2,
               e.MarginBounds.Top - (e.PageBounds.Height - g.VisibleClipBounds.Height) / 2,
               e.MarginBounds.Width, e.MarginBounds.Height);
         ScalingTranslation st = new ScalingTranslation(Picture.Bounds, port, true);
         Transformation old = Picture.Transformation;
         try
         {
            // make sure transformation reference is origin, or
            // calculations are broken
            Picture.TransformationReference = TransformationReference.Origin;
            Picture.ResetTransformation();
            Picture.TransformBy(st);
            Picture.RenderTo(g);
         }
         finally { Picture.Transformation = old; }
      }
   }

This code:
Code: Select all
ScalingTranslation st = new ScalingTranslation(Picture.Bounds, port, true);
centers the picture Bounds in the port.

Tips:
  • Use Stroke.Width of 1, not 0, if you wish to have a consistent line width. 0 means, "1 pixel" -- on a printer one pixel is far too small, and you may not see the line at all.
  • If you wish to print some other portion of the Picture, you will need to adjust the ScalingTranslation, st, in the code above. To print to a particular zoomed in area, assuming you have that area in the Picture child coordinate space, you substitute that rectangle for the Picture.Bounds in the ScalingTranslation calculation:
    Code: Select all
    ScalingTranslation st = new ScalingTranslation(zoomedArea, port, true);

    You need to compute zoomedArea in the Picture child space. If you want that to be the visible area in the Canvas, take an FRectangle of (0, 0, canvas.Width, canvas.Height), use the Picture RectangleDeviceToChild method to convert that to child coordinates. That is the zoomedArea above.
User avatar
Frank Hileman
Site Admin
 
Posts: 1399
Joined: Sun Jul 25, 2004 8:16 pm
Location: California

Return to Samples

Who is online

Users browsing this forum: No registered users and 2 guests

cron