From f415cab9ef1433413a1a68a982ee9b17c5a8deda Mon Sep 17 00:00:00 2001
From: Julian Smart <julian@anthemion.co.uk>
Date: Fri, 27 Oct 2006 13:07:40 +0000
Subject: [PATCH] Robert Lang's patch [ 1583183 ] Fixes printing/print preview
 inconsistencies

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42522 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/pagedlg.tex         |  33 ++-
 docs/latex/wx/print.tex           | 269 ++++++++++++++++++++----
 docs/latex/wx/tprint.tex          | 173 +++++++++++++--
 include/wx/cmndata.h              |   1 +
 include/wx/mac/carbon/dcprint.h   |   5 +-
 include/wx/mac/carbon/printdlg.h  |  45 +++-
 include/wx/mac/classic/dcprint.h  |   5 +-
 include/wx/mac/classic/printdlg.h |  38 +++-
 include/wx/motif/dcprint.h        |   2 +
 include/wx/msw/dcprint.h          |   2 +
 include/wx/msw/printdlg.h         |   3 +-
 include/wx/msw/printwin.h         |   3 +-
 include/wx/os2/dcprint.h          |   4 +-
 include/wx/palmos/dcprint.h       |   2 +
 include/wx/prntbase.h             |  43 +++-
 samples/printing/printing.cpp     | 222 +++++++++++++-------
 samples/printing/printing.h       |  16 +-
 src/common/prntbase.cpp           | 336 ++++++++++++++++++++++++------
 src/generic/printps.cpp           |  13 +-
 src/gtk/gnome/gprint.cpp          |  13 +-
 src/mac/carbon/dcprint.cpp        |  15 ++
 src/mac/carbon/printdlg.cpp       |  92 +++++++-
 src/mac/carbon/printmac.cpp       |  43 ++--
 src/mac/classic/dcprint.cpp       |  12 ++
 src/mac/classic/printdlg.cpp      |  83 ++++++++
 src/mac/classic/printmac.cpp      |  48 +++--
 src/msw/dcprint.cpp               |  13 ++
 src/msw/printdlg.cpp              |   2 +-
 src/msw/printwin.cpp              |  66 +++---
 src/os2/dcprint.cpp               |   9 +
 src/palmos/dcprint.cpp            |   8 +
 src/palmos/printpalm.cpp          |   1 +
 32 files changed, 1317 insertions(+), 303 deletions(-)

diff --git a/docs/latex/wx/pagedlg.tex b/docs/latex/wx/pagedlg.tex
index ba223977e3..b7d9cbafff 100644
--- a/docs/latex/wx/pagedlg.tex
+++ b/docs/latex/wx/pagedlg.tex
@@ -1,18 +1,26 @@
 \section{\class{wxPageSetupDialog}}\label{wxpagesetupdialog}
 
-This class represents the page setup common dialog. The page setup dialog is standard from
-Windows 95 on, replacing the print setup dialog (which is retained in Windows and wxWidgets
-for backward compatibility). On Windows 95 and NT 4.0 and above, the page setup dialog is
-native to the windowing system, otherwise it is emulated.
+This class represents the page setup common dialog. In MSW, the page setup
+dialog is standard from Windows 95 on, replacing the print setup dialog (which
+is retained in Windows and wxWidgets for backward compatibility). On Windows 95
+and NT 4.0 and above, the page setup dialog is native to the windowing system,
+otherwise it is emulated.
 
-The page setup dialog contains controls for paper size (A4, A5 etc.), orientation (landscape
-or portrait), and controls for setting left, top, right and bottom margin sizes in millimetres.
+The page setup dialog contains controls for paper size (A4, A5 etc.),
+orientation (landscape or portrait), and controls for setting left, top, right
+and bottom margin sizes in millimetres.
 
-When the dialog has been closed, you need to query the \helpref{wxPageSetupDialogData}{wxpagesetupdialogdata} object
-associated with the dialog.
+On Macintosh, the native page setup dialog is used, which lets you select paper
+size and orientation but it does not let you change the page margins.
 
-Note that the OK and Cancel buttons do not destroy the dialog; this must be done by the
-application.
+On other platforms, a generic dialog is used.
+
+When the dialog has been closed, you need to query the
+\helpref{wxPageSetupDialogData}{wxpagesetupdialogdata} object associated with
+the dialog.
+
+Note that the OK and Cancel buttons do not destroy the dialog; this must be done
+by the application.
 
 \wxheading{Derived from}
 
@@ -27,7 +35,9 @@ application.
 
 \wxheading{See also}
 
-\helpref{wxPrintDialog}{wxprintdialog}, \helpref{wxPageSetupDialogData}{wxpagesetupdialogdata}
+\helpref{Printing framework overview}{printingoverview}, 
+\helpref{wxPrintDialog}{wxprintdialog}, 
+\helpref{wxPageSetupDialogData}{wxpagesetupdialogdata}
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
@@ -82,6 +92,7 @@ user-interface configuration settings stored by wxPageSetupDialogData).
 
 \wxheading{See also}
 
+\helpref{Printing framework overview}{printingoverview}, 
 \helpref{wxPageSetupDialog}{wxpagesetupdialog}
 
 \latexignore{\rtfignore{\wxheading{Members}}}
diff --git a/docs/latex/wx/print.tex b/docs/latex/wx/print.tex
index 34dadf664c..3ef48559b7 100644
--- a/docs/latex/wx/print.tex
+++ b/docs/latex/wx/print.tex
@@ -16,6 +16,7 @@ between the print dialogs and the application.
 
 \wxheading{See also}
 
+\helpref{Printing framework overview}{printingoverview}, 
 \helpref{wxPrintDialog}{wxprintdialog}, 
 \helpref{wxPageSetupDialog}{wxpagesetupdialog}, 
 \helpref{wxPrintDialogData}{wxprintdialogdata}, 
@@ -371,6 +372,7 @@ a successfully dismissed print dialog.
 
 \wxheading{See also}
 
+\helpref{Printing framework overview}{printingoverview}, 
 \helpref{wxPrintDialog Overview}{wxprintdialogoverview}
 
 \latexignore{\rtfignore{\wxheading{Members}}}
@@ -436,7 +438,9 @@ It contains a wxPrintData object with underlying printing settings.
 
 \wxheading{See also}
 
-\helpref{wxPrintDialog}{wxprintdialog}, \helpref{wxPrintDialog Overview}{wxprintdialogoverview}
+\helpref{Printing framework overview}{printingoverview}, 
+\helpref{wxPrintDialog}{wxprintdialog}, 
+\helpref{wxPrintDialog Overview}{wxprintdialogoverview}
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
@@ -672,8 +676,11 @@ method of printing.
 
 \wxheading{See also}
 
-\helpref{Printing framework overview}{printingoverview}, \helpref{wxPrinterDC}{wxprinterdc}, \helpref{wxPrintDialog}{wxprintdialog},\rtfsp
-\helpref{wxPrintout}{wxprintout}, \helpref{wxPrintPreview}{wxprintpreview}.
+\helpref{Printing framework overview}{printingoverview}, 
+\helpref{wxPrinterDC}{wxprinterdc}, 
+\helpref{wxPrintDialog}{wxprintdialog}, 
+\helpref{wxPrintout}{wxprintout}, 
+\helpref{wxPrintPreview}{wxprintpreview}.
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
@@ -775,10 +782,10 @@ Windows 95, though retained for backward compatibility.
 
 \section{\class{wxPrinterDC}}\label{wxprinterdc}
 
-A printer device context is specific to Windows, and allows access to
-any printer with a Windows driver. See \helpref{wxDC}{wxdc} for further information
-on device contexts, and \helpref{wxDC::GetSize}{wxdcgetsize} for advice on
-achieving the correct scaling for the page.
+A printer device context is specific to MSW and Mac, and allows access to any
+printer with a Windows or Macintosh driver. See \helpref{wxDC}{wxdc} for further
+information on device contexts, and \helpref{wxDC::GetSize}{wxdcgetsize} for
+advice on achieving the correct scaling for the page.
 
 \wxheading{Derived from}
 
@@ -791,7 +798,8 @@ achieving the correct scaling for the page.
 
 \wxheading{See also}
 
-\helpref{wxDC}{wxdc}, \helpref{Printing framework overview}{printingoverview}
+\helpref{Printing framework overview}{printingoverview}, 
+\helpref{wxDC}{wxdc}
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
@@ -800,7 +808,7 @@ achieving the correct scaling for the page.
 
 \func{}{wxPrinterDC}{\param{const wxPrintData\& }{printData}}
 
-Pass a \helpref{wxPrintData}{wxprintdata} object with information
+Constructor. Pass a \helpref{wxPrintData}{wxprintdata} object with information
 necessary for setting up a suitable printer device context. This
 is the recommended way to construct a wxPrinterDC.  Make sure you 
 specify a reference to a \helpref{wxPrintData}{wxprintdata} object,
@@ -818,13 +826,43 @@ constructor was successful in creating a usable device context.
 
 This constructor is deprecated and retained only for backward compatibility.
 
+\membersection{wxPrinterDC::GetPaperRect}\label{wxprinterdcgetpaperrect}
+
+\func{wxRect}{wxPrinterDC::GetPaperRect}{}
+
+Return the rectangle in device coordinates that corresponds to the full paper
+area, including the nonprinting regions of the paper. The point (0,0) in device
+coordinates is the top left corner of the page rectangle, which is the printable
+area on MSW and Mac. The coordinates of the top left corner of the paper
+rectangle will therefore have small negative values, while the bottom right
+coordinates will be somewhat larger than the values returned by
+\helpref{wxDC::GetSize}{wxdcgetsize}.
+
+
 \section{\class{wxPrintout}}\label{wxprintout}
 
-This class encapsulates the functionality of printing out an
-application document. A new class must be derived and members
-overridden to respond to calls such as OnPrintPage and HasPage.
-Instances of this class are passed to wxPrinter::Print or a
-wxPrintPreview object to initiate printing or previewing.
+This class encapsulates the functionality of printing out an application
+document. A new class must be derived and members overridden to respond to calls
+such as OnPrintPage and HasPage and to render the print image onto an associated
+\helpref{wxDC}{wxdc}. Instances of this class are passed to wxPrinter::Print or
+to a wxPrintPreview object to initiate printing or previewing.
+
+Your derived wxPrintout is responsible for drawing both the preview image and
+the printed page. If your windows' drawing routines accept an arbitrary DC as an
+argument, you can re-use those routines within your wxPrintout subclass to draw
+the printout image. You may also add additional drawing elements within your
+wxPrintout subclass, like headers, footers, and/or page numbers. However, the
+image on the printed page will often differ from the image drawn on the screen,
+as will the print preview image -- not just in the presence of headers and
+footers, but typically in scale. A high-resolution printer presents a much
+larger drawing surface (i.e., a higher-resolution DC); a zoomed-out preview
+image presents a much smaller drawing surface (lower-resolution DC). By using
+the routines FitThisSizeToXXX() and/or MapScreenSizeToXXX() within your
+wxPrintout subclass to set the user scale and origin of the associated DC, you
+can easily use a single drawing routine to draw on your application's windows,
+to create the print preview image, and to create the printed paper image, and
+achieve a common appearance to the preview image and the printed page.
+
 
 \wxheading{Derived from}
 
@@ -836,8 +874,12 @@ wxPrintPreview object to initiate printing or previewing.
 
 \wxheading{See also}
 
-\helpref{Printing framework overview}{printingoverview}, \helpref{wxPrinterDC}{wxprinterdc}, \helpref{wxPrintDialog}{wxprintdialog},\rtfsp
-\helpref{wxPrinter}{wxprinter}, \helpref{wxPrintPreview}{wxprintpreview}
+\helpref{Printing framework overview}{printingoverview}, 
+\helpref{wxPrinterDC}{wxprinterdc}, 
+\helpref{wxPrintDialog}{wxprintdialog}, 
+\helpref{wxPageSetupDialog}{wxpagesetupdialog}, 
+\helpref{wxPrinter}{wxprinter}, 
+\helpref{wxPrintPreview}{wxprintpreview}
 
 \latexignore{\rtfignore{\wxheading{Members}}}
 
@@ -862,7 +904,7 @@ Destructor.
 \func{wxDC *}{GetDC}{\void}
 
 Returns the device context associated with the printout (given to the printout at start of
-printing or previewing). This will be a wxPrinterDC if printing under Windows,
+printing or previewing). This will be a wxPrinterDC if printing under Windows or Mac,
 a wxPostScriptDC if printing on other platforms, and a wxMemoryDC if previewing.
 
 
@@ -870,9 +912,10 @@ a wxPostScriptDC if printing on other platforms, and a wxMemoryDC if previewing.
 
 \func{void}{GetPageInfo}{\param{int *}{minPage}, \param{int *}{maxPage}, \param{int *}{pageFrom}, \param{int *}{pageTo}}
 
-Called by the framework to obtain information from the application about minimum and maximum page values that
-the user can select, and the required page range to be printed. By default this
-returns 1, 32000 for the page minimum and maximum values, and 1, 1 for the required page range.
+Called by the framework to obtain information from the application about minimum
+and maximum page values that the user can select, and the required page range to
+be printed. By default this returns 1, 32000 for the page minimum and maximum
+values, and 1, 1 for the required page range.
 
 If {\it minPage} is zero, the page number controls in the print dialog will be disabled.
 
@@ -902,12 +945,13 @@ Returns the size of the printer page in millimetres.
 
 \func{void}{GetPageSizePixels}{\param{int *}{w}, \param{int *}{h}}
 
-Returns the size of the printer page in pixels. These may not be the
-same as the values returned from \helpref{wxDC::GetSize}{wxdcgetsize} if
-the printout is being used for previewing, since in this case, a
-memory device context is used, using a bitmap size reflecting the current
-preview zoom. The application must take this discrepancy into account if
-previewing is to be supported.
+Returns the size of the printer page in pixels, called the \em{page rectangle}.
+The page rectangle has a top left corner at (0,0) and a bottom right corner at
+(w,h). These values may not be the same as the values returned from
+\helpref{wxDC::GetSize}{wxdcgetsize}; if the printout is being used for
+previewing, a memory device context is used, which uses a bitmap size reflecting
+the current preview zoom. The application must take this discrepancy into
+account if previewing is to be supported.
 
 \pythonnote{This method returns the output-only parameters as a tuple.}
 
@@ -915,14 +959,37 @@ previewing is to be supported.
 2-element list {\tt ( w, h )}}
 
 
+\membersection{wxPrintout::GetPaperRectPixels}\label{wxprintoutgetpaperrectpixels}
+
+\func{wxRect}{GetPaperRectPixels}{}
+
+Returns the rectangle that corresponds to the entire paper in pixels, called the
+\em{paper rectangle}. This distinction between paper rectangle and page
+rectangle reflects the fact that most printers cannot print all the way to the
+edge of the paper. The page rectangle is a rectangle whose top left corner is at
+(0,0) and whose width and height are given by
+\helpref{wxDC::GetPageSizePixels}{wxprintoutgetpagesizepixels}. On MSW and Mac,
+the page rectangle gives the printable area of the paper, while the paper
+rectangle represents the entire paper, including non-printable borders. Thus,
+the rectangle returned by GetPaperRectPixels will have a top left corner whose
+coordinates are small negative numbers and the bottom right corner will have
+values somewhat larger than the width and height given by
+\helpref{wxDC::GetPageSizePixels}{wxprintoutgetpagesizepixels}. On other
+platforms and for PostScript printing, the paper is treated as if its entire
+area were printable, so this function will return the same rectangle as the page
+rectangle.
+
+
 \membersection{wxPrintout::GetPPIPrinter}\label{wxprintoutgetppiprinter}
 
 \func{void}{GetPPIPrinter}{\param{int *}{w}, \param{int *}{h}}
 
 Returns the number of pixels per logical inch of the printer device context.
-Dividing the printer PPI by the screen PPI can give a suitable scaling
-factor for drawing text onto the printer. Remember to multiply
-this by a scaling factor to take the preview DC size into account.
+Dividing the printer PPI by the screen PPI can give a suitable scaling factor
+for drawing text onto the printer. Remember to multiply this by a scaling factor
+to take the preview DC size into account. Or you can just use the
+FitThisSizeToXXX() and MapScreenSizeToXXX routines below, which do most of the
+scaling calculations for you.
 
 \pythonnote{This method returns the output-only parameters as a tuple.}
 
@@ -935,9 +1002,9 @@ this by a scaling factor to take the preview DC size into account.
 \func{void}{GetPPIScreen}{\param{int *}{w}, \param{int *}{h}}
 
 Returns the number of pixels per logical inch of the screen device context.
-Dividing the printer PPI by the screen PPI can give a suitable scaling
-factor for drawing text onto the printer. Remember to multiply
-this by a scaling factor to take the preview DC size into account.
+Dividing the printer PPI by the screen PPI can give a suitable scaling factor
+for drawing text onto the printer. If you are doing your own scaling, remember
+to multiply this by a scaling factor to take the preview DC size into account.
 
 
 \membersection{wxPrintout::GetTitle}\label{wxprintoutgettitle}
@@ -968,6 +1035,134 @@ HasPage behaves as if the document has only one page.
 Returns true if the printout is currently being used for previewing.
 
 
+\membersection{wxPrintout::FitThisSizeToPaper}\label{wxprintoutfitthissizetopaper}
+
+\func{void}{FitThisSizeToPaper}{\param{const wxSize\& }{imageSize}}
+
+Set the user scale and device origin of the wxDC associated with this wxPrintout
+so that the given image size fits entirely within the paper and the origin is at
+the top left corner of the paper. Note that with most printers, the region
+around the edges of the paper are not printable so that the edges of the image
+could be cut off. Use this if you're managing your own page margins.
+
+\membersection{wxPrintout::FitThisSizeToPage}\label{wxprintoutfitthissizetopage}
+
+
+\func{void}{FitThisSizeToPage}{\param{const wxSize\& }{imageSize}}
+
+Set the user scale and device origin of the wxDC associated with this wxPrintout
+so that the given image size fits entirely within the page rectangle and the
+origin is at the top left corner of the page rectangle. On MSW and Mac, the page
+rectangle is the printable area of the page. On other platforms and PostScript
+printing, the page rectangle is the entire paper. Use this if you want your
+printed image as large as possible, but with the caveat that on some platforms, 
+portions of the image might be cut off at the edges.
+
+
+\membersection{wxPrintout::FitThisSizeToPageMargins}\label{wxprintoutfitthissizetopagemargins}
+
+\func{void}{FitThisSizeToPageMargins}{\param{const wxSize\& }{imageSize}, \param{const wxPageSetupDialogData\& }{pageSetupData}}
+
+Set the user scale and device origin of the wxDC associated with this wxPrintout
+so that the given image size fits entirely within the page margins set in the
+given wxPageSetupDialogData object. This function provides the greatest
+consistency across all platforms because it does not depend on having access to
+the printable area of the paper. Note that on Mac, the native wxPageSetupDialog
+does not let you set the page margins; you'll have to provide your own mechanism,
+or you can use the Mac-only class wxMacPageMarginsDialog.
+
+
+\membersection{wxPrintout::MapScreenSizeToPaper}\label{wxprintoutmapscreensizetopaper}
+
+\func{void}{MapScreenSizeToPaper}{}
+
+Set the user scale and device origin of the wxDC associated with this wxPrintout
+so that the printed page matches the screen size as closely as possible
+and the logical origin is in the top left corner of the paper rectangle.
+That is,
+a 100-pixel object on screen should appear at the same size on the printed page. (It
+will, of course, be larger or smaller in the preview image, depending on the zoom
+factor.) Use this if you want WYSIWYG behavior, e.g., in a text editor.
+
+
+\membersection{wxPrintout::MapScreenSizeToPage}\label{wxprintoutmapscreensizetopage}
+
+\func{void}{MapScreenSizeToPage}{}
+
+This sets the user scale of the wxDC assocated with this wxPrintout to the same
+scale as \helpref{MapScreenSizeToPaper}{wxprintoutmapscreensizetopaper} but sets
+the logical origin to the top left corner of the page rectangle.
+
+
+\membersection{wxPrintout::MapScreenSizeToPageMargins}\label{wxprintoutmapscreensizetopagemargins}
+
+\func{void}{MapScreenSizeToPageMargins}{\param{const wxPageSetupDialogData\& }{pageSetupData}}
+
+This sets the user scale of the wxDC assocated with this wxPrintout to the same
+scale as
+\helpref{MapScreenSizeToPageMargins}{wxprintoutmapscreensizetopagemargins} but
+sets the logical origin to the top left corner of the page margins specified by
+the given wxPageSetupDialogData object.
+
+
+\membersection{wxPrintout::MapScreenSizeToDevice}\label{wxprintoutmapscreensizetodevice}
+
+\func{void}{MapScreenSizeToDevice}{}
+
+Set the user scale and device origin of the wxDC associated with this wxPrintout
+so that one screen pixel maps to one device pixel on the DC. That is, the user
+scale is set to (1,1) and the device origin is set to (0,0). Use this if you
+want to do your own scaling prior to calling wxDC drawing calls, for example, if
+your underlying model is floating-point and you want to achieve maximum drawing
+precision on high-resolution printers. (Note that while the underlying drawing
+model of Mac OS X is floating-point, wxWidgets's drawing model scales from integer
+coordinates.) You can use the GetLogicalXXXRect() routines below to obtain the
+paper rectangle, page rectangle, or page margins rectangle to perform your own scaling.
+
+
+\membersection{wxPrintout::GetLogicalPaperRect}\label{wxprintoutgetlogicalpaperrect}
+
+\func{wxRect}{GetLogicalPaperRect}{}
+
+Return the rectangle corresponding to the paper in the associated wxDC's
+logical coordinates for the current user scale and device origin.
+
+
+\membersection{wxPrintout::GetLogicalPageRect}\label{wxprintoutgetlogicalpagerect}
+
+\func{wxRect}{GetLogicalPageRect}{}
+
+Return the rectangle corresponding to the page in the associated wxDC's
+logical coordinates for the current user scale and device origin. 
+On MSW and Mac, this will be the printable area of the paper. On other platforms
+and PostScript printing, this will be the full paper rectangle.
+
+
+\membersection{wxPrintout::GetLogicalPageMarginsRect}\label{wxprintoutgetlogicalpagemarginsrect}
+
+\func{wxRect}{GetLogicalPageMarginsRect}{\param{const wxPageSetupDialogData\& }{pageSetupData}}
+
+Return the rectangle corresponding to the page margins specified by the given
+wxPageSetupDialogData object in the associated wxDC's logical coordinates for the
+current user scale and device origin. The page margins are specified
+with respect to the edges of the paper on all platforms.
+
+
+\membersection{wxPrintout::SetLogicalOrigin}\label{wxprintoutsetlogicalorigin}
+
+\func{void}{SetLogicalOrigin}{\param{wxCoord }{x}, \param{wxCoord }{y}}
+
+Set the device origin of the associated wxDC so that the current logical point
+becomes the new logical origin.
+
+
+\membersection{wxPrintout::OffsetLogicalOrigin}\label{wxprintoutoffsetlogicalorigin}
+
+\func{void}{OffsetLogicalOrigin}{\param{wxCoord }{xoff}, \param{wxCoord }{yoff}}
+
+Shift the device origin by an amount specified in logical coordinates.
+
+
 \membersection{wxPrintout::OnBeginDocument}\label{wxprintoutonbegindocument}
 
 \func{bool}{OnBeginDocument}{\param{int}{ startPage}, \param{int}{ endPage}}
@@ -1046,9 +1241,13 @@ immediately after the frame is shown.
 
 \wxheading{See also}
 
-\overview{Printing framework overview}{printingoverview}, \helpref{wxPrinterDC}{wxprinterdc}, \helpref{wxPrintDialog}{wxprintdialog},\rtfsp
-\helpref{wxPrintout}{wxprintout}, \helpref{wxPrinter}{wxprinter},\rtfsp
-\helpref{wxPreviewCanvas}{wxpreviewcanvas}, \helpref{wxPreviewControlBar}{wxpreviewcontrolbar},\rtfsp
+\overview{Printing framework overview}{printingoverview}, 
+\helpref{wxPrinterDC}{wxprinterdc}, 
+\helpref{wxPrintDialog}{wxprintdialog}, 
+\helpref{wxPrintout}{wxprintout}, 
+\helpref{wxPrinter}{wxprinter}, 
+\helpref{wxPreviewCanvas}{wxpreviewcanvas}, 
+\helpref{wxPreviewControlBar}{wxpreviewcontrolbar}, 
 \helpref{wxPreviewFrame}{wxpreviewframe}.
 
 \latexignore{\rtfignore{\wxheading{Members}}}
diff --git a/docs/latex/wx/tprint.tex b/docs/latex/wx/tprint.tex
index e22b0c5b8c..20ad4d355b 100644
--- a/docs/latex/wx/tprint.tex
+++ b/docs/latex/wx/tprint.tex
@@ -4,34 +4,36 @@ Classes: \helpref{wxPrintout}{wxprintout},
 \helpref{wxPrinter}{wxprinter}, 
 \helpref{wxPrintPreview}{wxprintpreview}, 
 \helpref{wxPrinterDC}{wxprinterdc}, 
+\helpref{wxPostScriptDC}{wxpostscriptdc}, 
 \helpref{wxPrintDialog}{wxprintdialog}, 
 \helpref{wxPrintData}{wxprintdata}, 
 \helpref{wxPrintDialogData}{wxprintdialogdata}, 
 \helpref{wxPageSetupDialog}{wxpagesetupdialog}, 
 \helpref{wxPageSetupDialogData}{wxpagesetupdialogdata}
 
-The printing framework relies on the application to provide classes
-whose member functions can respond to particular requests, such
-as `print this page' or `does this page exist in the document?'.
-This method allows wxWidgets to take over the housekeeping duties of
-turning preview pages, calling the print dialog box, creating
-the printer device context, and so on: the application can concentrate
+The printing framework relies on the application to provide classes whose member
+functions can respond to particular requests, such as `print this page' or `does
+this page exist in the document?'. This method allows wxWidgets to take over the
+housekeeping duties of turning preview pages, calling the print dialog box,
+creating the printer device context, and so on: the application can concentrate
 on the rendering of the information onto a device context.
 
-The \helpref{document/view framework}{docviewoverview} creates a default
-wxPrintout object for every view, calling wxView::OnDraw to achieve a
-prepackaged print/preview facility.
+In most cases, the only class you will need to derive from is
+\helpref{wxPrintout}{wxprintout}; all others will be used as-is.
+
+A brief description of each class's role and how they work together follows.
+
+\subsection{\helpref{wxPrintout}{wxprintout}}
 
-A document's printing ability is represented in an application by a
-derived wxPrintout class. This class prints a page on request, and can
-be passed to the Print function of a wxPrinter object to actually print
-the document, or can be passed to a wxPrintPreview object to initiate
-previewing. The following code (from the printing sample) shows how easy
-it is to initiate printing, previewing and the print setup dialog, once the wxPrintout
-functionality has been defined. Notice the use of MyPrintout for
-both printing and previewing. All the preview user interface functionality
-is taken care of by wxWidgets. For details on how MyPrintout is defined,
-please look at the printout sample code.
+A document's printing ability is represented in an application by a derived
+wxPrintout class. This class prints a page on request, and can be passed to the
+Print function of a wxPrinter object to actually print the document, or can be
+passed to a wxPrintPreview object to initiate previewing. The following code
+(from the printing sample) shows how easy it is to initiate printing, previewing
+and the print setup dialog, once the wxPrintout functionality has been defined.
+Notice the use of MyPrintout for both printing and previewing. All the preview
+user interface functionality is taken care of by wxWidgets. For more details on how
+MyPrintout is defined, please look at the printout sample code.
 
 \begin{verbatim}
     case WXPRINT_PRINT:
@@ -53,6 +55,139 @@ please look at the printout sample code.
     }
 \end{verbatim}
 
+Class \helpref{wxPrintout}{wxprintout} assembles the printed page and (using
+your subclass's overrides) writes requested pages to a \helpref{wxDC}{wxdc} that
+is passed to it. This wxDC could be a \helpref{wxMemoryDC}{wxmemorydc} (for
+displaying the preview image on-screen), a \helpref{wxPrinterDC}{wxprinterdc}
+(for printing under MSW and Mac), or a \helpref{wxPostScriptDC}{wxpostscriptdc}
+(for printing under GTK or generating PostScript output).
+
+The \helpref{document/view framework}{docviewoverview} creates a default
+wxPrintout object for every view, calling wxView::OnDraw to achieve a
+prepackaged print/preview facility.
+
+If your window classes have a Draw(wxDC *dc) routine to do screen rendering,
+your wxPrintout subclass will typically call those routines to create portions
+of the image on your printout. Your wxPrintout subclass can also make its own
+calls to its wxDC to draw headers, footers, page numbers, etc.
+
+The scaling of the drawn image typically differs from the screen to the preview
+and printed images. This class provides a set of routines named
+FitThisSizeToXXX(), MapScreenSizeToXXX(), and GetLogicalXXXRect, which can be
+used to set the user scale and origin of the wxPrintout's DC so that your class
+can easily map your image to the printout withough getting into the details of
+screen and printer PPI and scaling. See the printing sample for examples of how
+these routines are used.
+
+\subsection{\helpref{wxPrinter}{wxprinter}}
+
+Class wxPrinter encapsulates the platform-dependent print function with a common
+interface. In most cases, you will not need to derive a class from wxPrinter;
+simply create a wxPrinter object in your Print function as in the example above.
+
+\subsection{\helpref{wxPrintPreview}{wxprintpreview}}
+
+Class wxPrintPreview manages the print preview process. Among other things, it
+constructs the wxDCs that get passed to your wxPrintout subclass for printing
+and manages the display of multiple pages, a zoomable preview image, and so
+forth. In most cases you will use this class as-is, but you can create your own
+subclass, for example, to change the layout or contents of the preview window.
+
+
+\subsection{\helpref{wxPrinterDC}{wxprinterdc}}
+
+Class wxPrinterDC is the wxDC that represents the actual printed page under MSW
+and Mac. During printing, an object of this class will be passed to your derived
+wxPrintout object to draw upon. The size of the wxPrinterDC will depend on the
+paper orientation and the resolution of the printer.
+
+There are two important rectangles in printing: the \em{page rectangle} defines
+the printable area seen by the application, and under MSW and Mac, it is the
+printable area specified by the printer. (For PostScript printing, the page
+rectangle is the entire page.) The inherited function
+\helpref{wxDC::GetSize}{wxdcgetsize} returns the page size in device pixels. The
+point (0,0) on the wxPrinterDC represents the top left corner of the page
+rectangle; that is, the page rect is given by wxRect(0, 0, w, h), where (w,h)
+are the values returned by GetSize.
+
+The \em{paper rectangle}, on the other hand, represents the entire paper area
+including the non-printable border. Thus, the coordinates of the top left corner
+of the paper rectangle will have small negative values, while the width and
+height will be somewhat larger than that of the page rectangle. The
+wxPrinterDC-specific function
+\helpref{wxPrinterDC::GetPaperRect}{wxprinterdcgetpaperrect} returns the paper
+rectangle of the given wxPrinterDC.
+
+\subsection{\helpref{wxPostScriptDC}{wxpostscriptdc}}
+
+Class wxPostScriptDC is the wxDC that represents the actual printed page under
+GTK and other PostScript printing. During printing, an object of this class will
+be passed to your derived wxPrintout object to draw upon. The size of the
+wxPostScriptDC will depend upon the \helpref{wxPrintData}{wxprintdata} used to
+construct it.
+
+Unlike a wxPrinterDC, there is no distinction between the page rectangle and the
+paper rectangle in a wxPostScriptDC; both rectangles are taken to represent the
+entire sheet of paper.
+
+\subsection{\helpref{wxPrintDialog}{wxprintdialog}}
+
+Class wxPrintDialog puts up the standard print dialog, which allows you to
+select the page range for printing (as well as many other print settings, which
+may vary from platform to platform). You provide an object of type
+\helpref{wxPrintDialogData}{wxprintdialogdata} to the wxPrintDialog at
+construction, which is used to populate the dialog.
+
+\subsection{\helpref{wxPrintData}{wxprintdata}}
+
+Class wxPrintData is a subset of wxPrintDialogData that is used (internally) to
+initialize a wxPrinterDC or wxPostScriptDC. (In fact, a wxPrintData is a data
+member of a wxPrintDialogData and a wxPageSetupDialogData). Essentially,
+wxPrintData contains those bits of information from the two dialogs necessary to
+configure the wxPrinterDC or wxPostScriptDC (e.g., size, orientation, etc.). You
+might wish to create a global instance of this object to provide call-to-call
+persistence to your application's print settings.
+
+\subsection{\helpref{wxPrintDialogData}{wxprintdialogdata}}
+
+Class wxPrintDialogData contains the settings entered by the user in the print
+dialog. It contains such things as page range, number of copies, and so forth.
+In most cases, you won't need to access this information; the framework takes
+care of asking your wxPrintout derived object for the pages requested by the
+user.
+
+\subsection{\helpref{wxPageSetupDialog}{wxpagesetupdialog}}
+
+Class wxPageSetupDialog puts up the standard page setup dialog, which allows you
+to specify the orientation, paper size, and related settings. You provide it
+with a wxPageSetupDialogData object at intialization, which is used to populate
+the dialog; when the dialog is dismissed, this object contains the settings
+chosen by the user, including orientation and/or page margins.
+
+Note that on Macintosh, the native page setup dialog does not contain entries
+that allow you to change the page margins. You can use the Mac-specific class
+wxMacPageMarginsDialog (which, like wxPageSetupDialog, takes a
+wxPageSetupDialogData object in its constructor) to provide this capability; see
+the printing sample for an example.
+
+\subsection{\helpref{wxPageSetupDialogData}{wxpagesetupdialogdata}}
+
+Class wxPageSetupDialogData contains settings affecting the page size (paper
+size), orientation, margins, and so forth. Note that not all platforms populate
+all fields; for example, the MSW page setup dialog lets you set the page margins
+while the Mac setup dialog does not.
+
+You will typically create a global instance of each of a wxPrintData and
+wxPageSetupDialogData at program initiation, which will contain the default
+settings provided by the system. Each time the user calls up either the
+wxPrintDialog or the wxPageSetupDialog, you pass these data structures to
+initialize the dialog values and to be updated by the dialog. The framework then
+queries these data structures to get information like the printed page range
+(from the wxPrintDialogData) or the paper size and/or page orientation (from the
+wxPageSetupDialogData).
+
+
+
 \section{Printing under Unix (GTK+)}\label{unixprinting}
 
 Printing under Unix has always been a cause of problems as Unix
diff --git a/include/wx/cmndata.h b/include/wx/cmndata.h
index 0b76205af7..a1a063ec27 100644
--- a/include/wx/cmndata.h
+++ b/include/wx/cmndata.h
@@ -419,6 +419,7 @@ public:
     wxPageSetupDialogData& operator=(const wxPrintData& data);
 
     wxPrintData& GetPrintData() { return m_printData; }
+    const wxPrintData& GetPrintData() const { return m_printData; }
     void SetPrintData(const wxPrintData& printData);
 
 private:
diff --git a/include/wx/mac/carbon/dcprint.h b/include/wx/mac/carbon/dcprint.h
index 2a5da88252..d2527e5991 100644
--- a/include/wx/mac/carbon/dcprint.h
+++ b/include/wx/mac/carbon/dcprint.h
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        dcprint.h
+// Name:        wx/mac/carbon/dcprint.h
 // Purpose:     wxPrinterDC class
 // Author:      Stefan Csomor
 // Modified by:
@@ -31,6 +31,9 @@ class WXDLLEXPORT wxPrinterDC: public wxDC
     virtual void EndDoc(void) ;
     virtual void StartPage(void) ;
     virtual void EndPage(void) ;
+
+    wxRect GetPaperRect();
+
     wxPrintData& GetPrintData() { return m_printData; }
     virtual wxSize GetPPI() const;
 #if wxMAC_USE_CORE_GRAPHICS
diff --git a/include/wx/mac/carbon/printdlg.h b/include/wx/mac/carbon/printdlg.h
index a12b983908..e25ddefe68 100644
--- a/include/wx/mac/carbon/printdlg.h
+++ b/include/wx/mac/carbon/printdlg.h
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        printdlg.h
+// Name:        wx/mac/carbon/printdlg.h
 // Purpose:     wxPrintDialog, wxPageSetupDialog classes.
 //              Use generic, PostScript version if no
 //              platform-specific implementation.
@@ -58,21 +58,54 @@ private:
 class WXDLLEXPORT wxMacPageSetupDialog: public wxPageSetupDialogBase
 {
 public:
-    wxMacPageSetupDialog(wxWindow *parent, wxPageSetupDialogData *data = NULL);
+    wxMacPageSetupDialog(wxWindow *parent, wxPageSetupData *data = NULL);
     virtual ~wxMacPageSetupDialog();
 
     virtual wxPageSetupData& GetPageSetupDialogData();
     
-    bool Create(wxWindow *parent, wxPageSetupDialogData *data = NULL);
+    bool Create(wxWindow *parent, wxPageSetupData *data = NULL);
     virtual int ShowModal();
   
 private:
-    wxPageSetupDialogData   m_pageSetupData;
+    wxPageSetupData   m_pageSetupData;
     wxWindow*               m_dialogParent;
   
 private:
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacPageSetupDialog)
 };
 
-#endif
-    // _WX_PRINTDLG_H_
+
+/*
+* wxMacPageMarginsDialog
+* A Mac dialog for setting the page margins separately from page setup since
+* (native) wxMacPageSetupDialog doesn't let you set margins.
+*/
+
+class WXDLLEXPORT wxMacPageMarginsDialog : public wxDialog
+{
+public:
+    wxMacPageMarginsDialog(wxFrame* parent, wxPageSetupData* data);
+    bool TransferToWindow();
+    bool TransferDataFromWindow();
+
+    virtual wxPageSetupData& GetPageSetupDialogData() { return *m_pageSetupDialogData; }
+
+private:
+    wxPageSetupData* m_pageSetupDialogData;
+    
+    wxPoint m_MinMarginTopLeft;
+    wxPoint m_MinMarginBottomRight;
+    wxTextCtrl *m_LeftMargin;
+    wxTextCtrl *m_TopMargin;
+    wxTextCtrl *m_RightMargin;
+    wxTextCtrl *m_BottomMargin;
+    
+    void GetMinMargins();
+    bool CheckValue(wxTextCtrl* textCtrl, int *value, int minValue, const wxString& name);
+    
+private:
+    DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacPageMarginsDialog)
+};
+
+
+#endif    // _WX_PRINTDLG_H_
diff --git a/include/wx/mac/classic/dcprint.h b/include/wx/mac/classic/dcprint.h
index 444295fda6..cb2d4da407 100644
--- a/include/wx/mac/classic/dcprint.h
+++ b/include/wx/mac/classic/dcprint.h
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        dcprint.h
+// Name:        wx/mac/classic/dcprint.h
 // Purpose:     wxPrinterDC class
 // Author:      Stefan Csomor
 // Modified by:
@@ -31,6 +31,9 @@ class WXDLLEXPORT wxPrinterDC: public wxDC
     virtual void EndDoc(void) ;
     virtual void StartPage(void) ;
     virtual void EndPage(void) ;
+
+    wxRect GetPaperRect();
+
     wxPrintData& GetPrintData() { return m_printData; }
     virtual void DoGetSize( int *width, int *height ) const;
     
diff --git a/include/wx/mac/classic/printdlg.h b/include/wx/mac/classic/printdlg.h
index ea04282cda..2bb57e93bc 100644
--- a/include/wx/mac/classic/printdlg.h
+++ b/include/wx/mac/classic/printdlg.h
@@ -59,11 +59,43 @@ class WXDLLEXPORT wxPageSetupDialog: public wxDialog
   bool Create(wxWindow *parent, wxPageSetupData *data = NULL);
   virtual int ShowModal();
 
-  inline wxPageSetupData& GetPageSetupData() { return m_pageSetupData; }
+  virtual wxPageSetupData& GetPageSetupDialogData() { return m_pageSetupData; }
  private:
   wxPageSetupData   m_pageSetupData;
   wxWindow*         m_dialogParent;
 };
 
-#endif
-    // _WX_PRINTDLG_H_
+
+/*
+* wxMacPageMarginsDialog
+* A Mac dialog for setting the page margins separately from page setup since
+* (native) wxMacPageSetupDialog doesn't let you set margins.
+*/
+
+class WXDLLEXPORT wxMacPageMarginsDialog : public wxDialog
+{
+public:
+    wxMacPageMarginsDialog(wxFrame* parent, wxPageSetupData* data);
+    bool TransferToWindow();
+    bool TransferDataFromWindow();
+    virtual wxPageSetupData& GetPageSetupDialogData() { return *m_pageSetupDialogData; }
+
+private:
+    wxPageSetupData* m_pageSetupDialogData;
+    
+    wxPoint m_MinMarginTopLeft;
+    wxPoint m_MinMarginBottomRight;
+    wxTextCtrl *m_LeftMargin;
+    wxTextCtrl *m_TopMargin;
+    wxTextCtrl *m_RightMargin;
+    wxTextCtrl *m_BottomMargin;
+    
+    void GetMinMargins();
+    bool CheckValue(wxTextCtrl* textCtrl, int *value, int minValue, const wxString& name);
+    
+private:
+    DECLARE_DYNAMIC_CLASS_NO_COPY(wxMacPageMarginsDialog)
+};
+
+
+#endif    // _WX_PRINTDLG_H_
diff --git a/include/wx/motif/dcprint.h b/include/wx/motif/dcprint.h
index 543879f38a..bd9687152f 100644
--- a/include/wx/motif/dcprint.h
+++ b/include/wx/motif/dcprint.h
@@ -22,6 +22,8 @@ public:
     // Create a printer DC
     wxPrinterDC(const wxString& driver, const wxString& device, const wxString& output, bool interactive = true, int orientation = wxPORTRAIT);
 
+    wxRect GetPaperRect();
+
     virtual ~wxPrinterDC();
 };
 
diff --git a/include/wx/msw/dcprint.h b/include/wx/msw/dcprint.h
index 8847a2d65a..29a79daf18 100644
--- a/include/wx/msw/dcprint.h
+++ b/include/wx/msw/dcprint.h
@@ -34,6 +34,8 @@ public:
     virtual void StartPage();
     virtual void EndPage();
 
+    wxRect GetPaperRect();
+
 protected:
     virtual void DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y,
                               bool useMask = false);
diff --git a/include/wx/msw/printdlg.h b/include/wx/msw/printdlg.h
index 1e81317e25..868ed30f76 100644
--- a/include/wx/msw/printdlg.h
+++ b/include/wx/msw/printdlg.h
@@ -68,11 +68,12 @@ public:
 
     wxPrintDialogData& GetPrintDialogData() { return m_printDialogData; }
     wxPrintData& GetPrintData() { return m_printDialogData.GetPrintData(); }
+
     virtual wxDC *GetPrintDC();
 
 private:
     wxPrintDialogData m_printDialogData;
-    wxDC*             m_printerDC;
+    wxPrinterDC*      m_printerDC;
     bool              m_destroyDC;
     wxWindow*         m_dialogParent;
     
diff --git a/include/wx/msw/printwin.h b/include/wx/msw/printwin.h
index 4f9d1b0fdb..64e171c9b0 100644
--- a/include/wx/msw/printwin.h
+++ b/include/wx/msw/printwin.h
@@ -29,7 +29,8 @@ public:
     virtual bool Print(wxWindow *parent,
                        wxPrintout *printout,
                        bool prompt = true);
-    virtual wxDC* PrintDialog(wxWindow *parent);
+
+    virtual wxDC *PrintDialog(wxWindow *parent);
     virtual bool Setup(wxWindow *parent);
 
 private:
diff --git a/include/wx/os2/dcprint.h b/include/wx/os2/dcprint.h
index c91a88849e..0cf75b37b1 100644
--- a/include/wx/os2/dcprint.h
+++ b/include/wx/os2/dcprint.h
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        dcprint.h
+// Name:        wx/os2/dcprint.h
 // Purpose:     wxPrinterDC class
 // Author:      David Webster
 // Modified by:
@@ -37,6 +37,8 @@ class WXDLLEXPORT wxPrinterDC: public wxDC
     void StartPage(void);
     void EndPage(void);
 
+    wxRect GetPaperRect();
+
 protected:
     virtual void DoDrawBitmap( const wxBitmap& rBmp
                               ,wxCoord         vX
diff --git a/include/wx/palmos/dcprint.h b/include/wx/palmos/dcprint.h
index b5b7701262..20758ead92 100644
--- a/include/wx/palmos/dcprint.h
+++ b/include/wx/palmos/dcprint.h
@@ -34,6 +34,8 @@ public:
     virtual void StartPage();
     virtual void EndPage();
 
+    wxRect GetPaperRect();
+
 protected:
     virtual void DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y,
                               bool useMask = FALSE);
diff --git a/include/wx/prntbase.h b/include/wx/prntbase.h
index 43376b04e7..d3de6928d3 100644
--- a/include/wx/prntbase.h
+++ b/include/wx/prntbase.h
@@ -261,6 +261,22 @@ public:
 
     wxDC *GetDC() const { return m_printoutDC; }
     void SetDC(wxDC *dc) { m_printoutDC = dc; }
+
+    void FitThisSizeToPaper(const wxSize& imageSize);
+    void FitThisSizeToPage(const wxSize& imageSize);
+    void FitThisSizeToPageMargins(const wxSize& imageSize, const wxPageSetupDialogData& pageSetupData);
+    void MapScreenSizeToPaper();
+    void MapScreenSizeToPage();
+    void MapScreenSizeToPageMargins(const wxPageSetupDialogData& pageSetupData);
+    void MapScreenSizeToDevice();
+
+    wxRect GetLogicalPaperRect() const;
+    wxRect GetLogicalPageRect() const;
+    wxRect GetLogicalPageMarginsRect(const wxPageSetupDialogData& pageSetupData) const;
+
+    void SetLogicalOrigin(wxCoord x, wxCoord y);
+    void OffsetLogicalOrigin(wxCoord xoff, wxCoord yoff);
+
     void SetPageSizePixels(int w, int  h) { m_pageWidthPixels = w; m_pageHeightPixels = h; }
     void GetPageSizePixels(int *w, int  *h) const { *w = m_pageWidthPixels; *h = m_pageHeightPixels; }
     void SetPageSizeMM(int w, int  h) { m_pageWidthMM = w; m_pageHeightMM = h; }
@@ -271,6 +287,9 @@ public:
     void SetPPIPrinter(int x, int y) { m_PPIPrinterX = x; m_PPIPrinterY = y; }
     void GetPPIPrinter(int *x, int *y) const { *x = m_PPIPrinterX; *y = m_PPIPrinterY; }
 
+    void SetPaperRectPixels(const wxRect& paperRectPixels) { m_paperRectPixels = paperRectPixels; }
+    wxRect GetPaperRectPixels() const { return m_paperRectPixels; }
+
     virtual bool IsPreview() const { return m_isPreview; }
 
     virtual void SetIsPreview(bool p) { m_isPreview = p; }
@@ -290,6 +309,8 @@ private:
     int              m_PPIPrinterX;
     int              m_PPIPrinterY;
 
+    wxRect           m_paperRectPixels;
+
     bool             m_isPreview;
 
 private:
@@ -297,8 +318,11 @@ private:
     DECLARE_NO_COPY_CLASS(wxPrintout)
 };
 
+//----------------------------------------------------------------------------
+// wxPreviewCanvas
+//----------------------------------------------------------------------------
+
 /*
- * wxPreviewCanvas
  * Canvas upon which a preview is drawn.
  */
 
@@ -330,8 +354,11 @@ private:
     DECLARE_NO_COPY_CLASS(wxPreviewCanvas)
 };
 
+//----------------------------------------------------------------------------
+// wxPreviewFrame
+//----------------------------------------------------------------------------
+
 /*
- * wxPreviewFrame
  * Default frame for showing preview.
  */
 
@@ -366,8 +393,11 @@ private:
     DECLARE_NO_COPY_CLASS(wxPreviewFrame)
 };
 
+//----------------------------------------------------------------------------
+// wxPreviewControlBar
+//----------------------------------------------------------------------------
+
 /*
- * wxPreviewControlBar
  * A panel with buttons for controlling a print preview.
  * The programmer may wish to use other means for controlling
  * the print preview.
@@ -479,6 +509,10 @@ public:
     virtual wxFrame *GetFrame() const;
     virtual wxPreviewCanvas *GetCanvas() const;
 
+    // This is a helper routine, used by the next 4 routines.
+
+    virtual void CalcRects(wxPreviewCanvas *canvas, wxRect& printableAreaRect, wxRect& paperRect);
+
     // The preview canvas should call this from OnPaint
     virtual bool PaintPage(wxPreviewCanvas *canvas, wxDC& dc);
 
@@ -526,7 +560,8 @@ protected:
     wxPrintout*       m_printPrintout;
     int               m_currentPage;
     int               m_currentZoom;
-    float             m_previewScale;
+    float             m_previewScaleX;
+    float             m_previewScaleY;
     int               m_topMargin;
     int               m_leftMargin;
     int               m_pageWidth;
diff --git a/samples/printing/printing.cpp b/samples/printing/printing.cpp
index 0035f4b1ad..bfe2f16192 100644
--- a/samples/printing/printing.cpp
+++ b/samples/printing/printing.cpp
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        printing.cpp
+// Name:        samples/printing.cpp
 // Purpose:     Printing demo for wxWidgets
 // Author:      Julian Smart
 // Modified by:
@@ -40,6 +40,10 @@
 #include "wx/generic/prntdlgg.h"
 #endif
 
+#ifdef __WXMAC__
+#include "wx/mac/printdlg.h"
+#endif
+
 #include "printing.h"
 
 #ifndef __WXMSW__
@@ -60,7 +64,7 @@ MyFrame   *frame = (MyFrame *) NULL;
 wxPrintData *g_printData = (wxPrintData*) NULL ;
 
 // Global page setup data
-wxPageSetupData* g_pageSetupData = (wxPageSetupData*) NULL;
+wxPageSetupDialogData* g_pageSetupData = (wxPageSetupDialogData*) NULL;
 
 // Main proc
 IMPLEMENT_APP(MyApp)
@@ -78,10 +82,20 @@ bool MyApp::OnInit(void)
     m_testFont.Create(10, wxSWISS, wxNORMAL, wxNORMAL);
 
     g_printData = new wxPrintData;
+    // Set an initial paper size
+//    g_printData->SetPaperId(wxPAPER_LETTER); // for Americans
+    g_printData->SetPaperId(wxPAPER_A4);    // for everyone else    
+
     g_pageSetupData = new wxPageSetupDialogData;
+    // copy over initial paper size from print record
+    (*g_pageSetupData) = *g_printData;
+    // Set some initial page margins in mm. 
+    g_pageSetupData->SetMarginTopLeft(wxPoint(15, 15));
+    g_pageSetupData->SetMarginBottomRight(wxPoint(15, 15));
 
     // Create the main frame window
-    frame = new MyFrame((wxFrame *) NULL, _T("wxWidgets Printing Demo"), wxPoint(0, 0), wxSize(400, 400));
+    frame = new MyFrame((wxFrame *) NULL, _T("wxWidgets Printing Demo"), 
+        wxPoint(0, 0), wxSize(400, 400));
 
 #if wxUSE_STATUSBAR
     // Give it a status line
@@ -96,6 +110,9 @@ bool MyApp::OnInit(void)
 
     file_menu->Append(WXPRINT_PRINT, _T("&Print..."),              _T("Print"));
     file_menu->Append(WXPRINT_PAGE_SETUP, _T("Page Set&up..."),              _T("Page setup"));
+#ifdef __WXMAC__
+    file_menu->Append(WXPRINT_PAGE_MARGINS, _T("Page Margins..."), _T("Page margins"));
+#endif
     file_menu->Append(WXPRINT_PREVIEW, _T("Print Pre&view"),              _T("Preview"));
 
 #if wxUSE_ACCEL
@@ -112,6 +129,7 @@ bool MyApp::OnInit(void)
     file_menu->Append(WXPRINT_PAGE_SETUP_PS, _T("Page Setup PostScript..."),              _T("Page setup (PostScript)"));
     file_menu->Append(WXPRINT_PREVIEW_PS, _T("Print Preview PostScript"),              _T("Preview (PostScript)"));
 #endif
+
     file_menu->AppendSeparator();
     file_menu->Append(WXPRINT_ANGLEUP, _T("Angle up\tAlt-U"),                _T("Raise rotated text angle"));
     file_menu->Append(WXPRINT_ANGLEDOWN, _T("Angle down\tAlt-D"),            _T("Lower rotated text angle"));
@@ -166,6 +184,9 @@ EVT_MENU(WXPRINT_PRINT_PS, MyFrame::OnPrintPS)
 EVT_MENU(WXPRINT_PREVIEW_PS, MyFrame::OnPrintPreviewPS)
 EVT_MENU(WXPRINT_PAGE_SETUP_PS, MyFrame::OnPageSetupPS)
 #endif
+#ifdef __WXMAC__
+EVT_MENU(WXPRINT_PAGE_MARGINS, MyFrame::OnPageMargins)
+#endif
 EVT_MENU(WXPRINT_ANGLEUP, MyFrame::OnAngleUp)
 EVT_MENU(WXPRINT_ANGLEDOWN, MyFrame::OnAngleDown)
 END_EVENT_TABLE()
@@ -236,8 +257,8 @@ void MyFrame::OnPageSetup(wxCommandEvent& WXUNUSED(event))
     wxPageSetupDialog pageSetupDialog(this, g_pageSetupData);
     pageSetupDialog.ShowModal();
 
-    (*g_printData) = pageSetupDialog.GetPageSetupData().GetPrintData();
-    (*g_pageSetupData) = pageSetupDialog.GetPageSetupData();
+    (*g_printData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
+    (*g_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
 }
 
 #if defined(__WXMSW__) && wxTEST_POSTSCRIPT_IN_MSW
@@ -268,8 +289,22 @@ void MyFrame::OnPageSetupPS(wxCommandEvent& WXUNUSED(event))
     wxGenericPageSetupDialog pageSetupDialog(this, g_pageSetupData);
     pageSetupDialog.ShowModal();
 
-    (*g_printData) = pageSetupDialog.GetPageSetupData().GetPrintData();
-    (*g_pageSetupData) = pageSetupDialog.GetPageSetupData();
+    (*g_printData) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
+    (*g_pageSetupData) = pageSetupDialog.GetPageSetupDialogData();
+}
+#endif
+
+
+#ifdef __WXMAC__
+void MyFrame::OnPageMargins(wxCommandEvent& WXUNUSED(event))
+{
+    (*g_pageSetupData) = *g_printData;
+
+    wxMacPageMarginsDialog pageMarginsDialog(this, g_pageSetupData);
+    pageMarginsDialog.ShowModal();
+
+    (*g_printData) = pageMarginsDialog.GetPageSetupDialogData().GetPrintData();
+    (*g_pageSetupData) = pageMarginsDialog.GetPageSetupDialogData();
 }
 #endif
 
@@ -294,12 +329,23 @@ void MyFrame::OnAngleDown(wxCommandEvent& WXUNUSED(event))
 
 void MyFrame::Draw(wxDC& dc)
 {
+    // This routine just draws a bunch of random stuff on the screen so that we
+    // can check that different types of object are being drawn consistently
+    // between the screen image, the print preview image (at various zoom
+    // levels), and the printed page.
     dc.SetBackground(*wxWHITE_BRUSH);
     dc.Clear();
     dc.SetFont(wxGetApp().m_testFont);
 
     dc.SetBackgroundMode(wxTRANSPARENT);
 
+    dc.SetPen(*wxBLACK_PEN);
+    dc.SetBrush(*wxLIGHT_GREY_BRUSH);
+    dc.DrawRectangle(0, 0, 230, 350);
+    dc.DrawLine(0, 0, 229, 349);
+    dc.DrawLine(229, 0, 0, 349);
+    dc.SetBrush(*wxTRANSPARENT_BRUSH);
+
     dc.SetBrush(*wxCYAN_BRUSH);
     dc.SetPen(*wxRED_PEN);
 
@@ -313,7 +359,6 @@ void MyFrame::Draw(wxDC& dc)
 
     dc.DrawText( wxT("Test message: this is in 10 point text"), 10, 180);
     
-
 #if wxUSE_UNICODE
     char *test = "Hebrew    ×©××× -- Japanese (æ¥æ¬èª)";
     wxString tmp = wxConvUTF8.cMB2WC( test );
@@ -357,10 +402,6 @@ void MyFrame::Draw(wxDC& dc)
     str.Printf( wxT("---- Text at angle %d ----"), i );
     dc.DrawRotatedText( str, 100, 300, i );
 
-    dc.SetPen(* wxBLACK_PEN);
-    dc.DrawLine(0, 0, 200, 200);
-    dc.DrawLine(200, 0, 0, 200);
-
     wxIcon my_icon = wxICON(mondrian) ;
 
     dc.DrawIcon( my_icon, 100, 100);
@@ -378,14 +419,12 @@ BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
 EVT_MOUSE_EVENTS(MyCanvas::OnEvent)
 END_EVENT_TABLE()
 
-// Define a constructor for my canvas
 MyCanvas::MyCanvas(wxFrame *frame, const wxPoint& pos, const wxSize& size, long style):
     wxScrolledWindow(frame, wxID_ANY, pos, size, style)
 {
     SetBackgroundColour(* wxWHITE);
 }
 
-// Define the repainting behaviour
 void MyCanvas::OnDraw(wxDC& dc)
 {
     frame->Draw(dc);
@@ -401,16 +440,16 @@ bool MyPrintout::OnPrintPage(int page)
     if (dc)
     {
         if (page == 1)
-            DrawPageOne(dc);
+            DrawPageOne();
         else if (page == 2)
-            DrawPageTwo(dc);
-
-        dc->SetDeviceOrigin(0, 0);
-        dc->SetUserScale(1.0, 1.0);
+            DrawPageTwo();
 
+        // Draw page numbers at top left corner of printable area, sized so that
+        // screen size of text matches paper size.
+        MapScreenSizeToPage();
         wxChar buf[200];
         wxSprintf(buf, wxT("PAGE %d"), page);
-        dc->DrawText(buf, 10, 10);
+        dc->DrawText(buf, 0, 0);
 
         return true;
     }
@@ -439,83 +478,120 @@ bool MyPrintout::HasPage(int pageNum)
     return (pageNum == 1 || pageNum == 2);
 }
 
-void MyPrintout::DrawPageOne(wxDC *dc)
+void MyPrintout::DrawPageOne()
 {
-    // You might use THIS code if you were scaling
-    // graphics of known size to fit on the page.
-
-    // We know the graphic is 200x200. If we didn't know this,
-    // we'd need to calculate it.
-    float maxX = 200;
-    float maxY = 200;
-
-    // Let's have at least 50 device units margin
-    float marginX = 50;
-    float marginY = 50;
-
-    // Add the margin to the graphic size
-    maxX += (2*marginX);
-    maxY += (2*marginY);
-
-    // Get the size of the DC in pixels
-    int w, h;
-    dc->GetSize(&w, &h);
-
-    // Calculate a suitable scaling factor
-    float scaleX=(float)(w/maxX);
-    float scaleY=(float)(h/maxY);
-
-    // Use x or y scaling factor, whichever fits on the DC
-    float actualScale = wxMin(scaleX,scaleY);
-
-    // Calculate the position on the DC for centring the graphic
-    float posX = (float)((w - (200*actualScale))/2.0);
-    float posY = (float)((h - (200*actualScale))/2.0);
-
-    // Set the scale and origin
-    dc->SetUserScale(actualScale, actualScale);
-    dc->SetDeviceOrigin( (long)posX, (long)posY );
-
-    frame->Draw(*dc);
+    // You might use THIS code if you were scaling graphics of known size to fit
+    // on the page. The commented-out code illustrates different ways of scaling
+    // the graphics.
+
+    // We know the graphic is 230x350. If we didn't know this, we'd need to
+    // calculate it.
+    wxCoord maxX = 230;
+    wxCoord maxY = 350;
+
+    // This sets the user scale and origin of the DC so that the image fits
+    // within the paper rectangle (but the edges could be cut off by printers
+    // that can't print to the edges of the paper -- which is most of them. Use
+    // this if your image already has its own margins.
+//    FitThisSizeToPaper(wxSize(maxX, maxY));
+//    wxRect fitRect = GetLogicalPaperRect();
+
+    // This sets the user scale and origin of the DC so that the image fits
+    // within the page rectangle, which is the printable area on Mac and MSW
+    // and is the entire page on other platforms.
+//    FitThisSizeToPage(wxSize(maxX, maxY));
+//    wxRect fitRect = GetLogicalPageRect();
+
+    // This sets the user scale and origin of the DC so that the image fits
+    // within the page margins as specified by g_PageSetupData, which you can
+    // change (on some platforms, at least) in the Page Setup dialog. Note that
+    // on Mac, the native Page Setup dialog doesn't let you change the margins
+    // of a wxPageSetupDialogData object, so you'll have to write your own dialog or
+    // use the Mac-only wxMacPageMarginsDialog, as we do in this program.
+    FitThisSizeToPageMargins(wxSize(maxX, maxY), *g_pageSetupData);
+    wxRect fitRect = GetLogicalPageMarginsRect(*g_pageSetupData);
+
+    // This sets the user scale and origin of the DC so that the image appears
+    // on the paper at the same size that it appears on screen (i.e., 10-point
+    // type on screen is 10-point on the printed page) and is positioned in the
+    // top left corner of the page rectangle (just as the screen image appears
+    // in the top left corner of the window).
+//    MapScreenSizeToPage();
+//    wxRect fitRect = GetLogicalPageRect();
+
+    // You could also map the screen image to the entire paper at the same size
+    // as it appears on screen.
+//    MapScreenSizeToPaper();
+//    wxRect fitRect = GetLogicalPaperRect();
+
+    // You might also wish to do you own scaling in order to draw objects at
+    // full native device resolution. In this case, you should do the following.
+    // Note that you can use the GetLogicalXXXRect() commands to obtain the
+    // appropriate rect to scale to.
+//    MapScreenSizeToDevice();
+//    wxRect fitRect = GetLogicalPageRect();
+
+    // Each of the preceding Fit or Map routines positions the origin so that
+    // the drawn image is positioned at the top left corner of the reference
+    // rectangle. You can easily center or right- or bottom-justify the image as
+    // follows.
+
+    // This offsets the image so that it is centered within the reference
+    // rectangle defined above.
+    wxCoord xoff = (fitRect.width - maxX) / 2;
+    wxCoord yoff = (fitRect.height - maxY) / 2;
+    OffsetLogicalOrigin(xoff, yoff);
+
+    // This offsets the image so that it is positioned at the bottom right of
+    // the reference rectangle defined above.
+//    wxCoord xoff = (fitRect.width - maxX);
+//    wxCoord yoff = (fitRect.height - maxY);
+//    OffsetLogicalOrigin(xoff, yoff);
+
+    frame->Draw(*GetDC());
 }
 
-void MyPrintout::DrawPageTwo(wxDC *dc)
+void MyPrintout::DrawPageTwo()
 {
     // You might use THIS code to set the printer DC to ROUGHLY reflect
     // the screen text size. This page also draws lines of actual length
     // 5cm on the page.
 
+    // Compare this to DrawPageOne(), which uses the really convenient routines
+    // from wxPrintout to fit the screen image onto the printed page. This page
+    // illustrates how to do all the scaling calculations yourself, if you're so
+    // inclined.
+
+    wxDC *dc = GetDC();
+
     // Get the logical pixels per inch of screen and printer
     int ppiScreenX, ppiScreenY;
     GetPPIScreen(&ppiScreenX, &ppiScreenY);
     int ppiPrinterX, ppiPrinterY;
     GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
 
-    // This scales the DC so that the printout roughly represents the
-    // the screen scaling. The text point size _should_ be the right size
-    // but in fact is too small for some reason. This is a detail that will
-    // need to be addressed at some point but can be fudged for the
-    // moment.
+    // This scales the DC so that the printout roughly represents the the screen
+    // scaling. The text point size _should_ be the right size but in fact is
+    // too small for some reason. This is a detail that will need to be
+    // addressed at some point but can be fudged for the moment.
     float scale = (float)((float)ppiPrinterX/(float)ppiScreenX);
 
-    // Now we have to check in case our real page size is reduced
-    // (e.g. because we're drawing to a print preview memory DC)
+    // Now we have to check in case our real page size is reduced (e.g. because
+    // we're drawing to a print preview memory DC)
     int pageWidth, pageHeight;
     int w, h;
     dc->GetSize(&w, &h);
     GetPageSizePixels(&pageWidth, &pageHeight);
 
-    // If printer pageWidth == current DC width, then this doesn't
-    // change. But w might be the preview bitmap width, so scale down.
+    // If printer pageWidth == current DC width, then this doesn't change. But w
+    // might be the preview bitmap width, so scale down.
     float overallScale = scale * (float)(w/(float)pageWidth);
     dc->SetUserScale(overallScale, overallScale);
 
-    // Calculate conversion factor for converting millimetres into
-    // logical units.
-    // There are approx. 25.4 mm to the inch. There are ppi
-    // device units to the inch. Therefore 1 mm corresponds to
-    // ppi/25.4 device units. We also divide by the
-    // screen-to-printer scaling factor, because we need to
+    // Calculate conversion factor for converting millimetres into logical
+    // units. There are approx. 25.4 mm to the inch. There are ppi device units
+    // to the inch. Therefore 1 mm corresponds to ppi/25.4 device units. We also
+    // divide by the screen-to-printer scaling factor, because we need to
     // unscale to pass logical units to DrawLine.
 
     // Draw 50 mm by 50 mm L shape
diff --git a/samples/printing/printing.h b/samples/printing/printing.h
index f3c2b6d98c..9ccd72a277 100644
--- a/samples/printing/printing.h
+++ b/samples/printing/printing.h
@@ -1,5 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        printing.h
+// Name:        samples/printing.h
+
 // Purpose:     Printing demo for wxWidgets
 // Author:      Julian Smart
 // Modified by:
@@ -46,6 +47,9 @@ class MyFrame: public wxFrame
     void OnPrintPreviewPS(wxCommandEvent& event);
     void OnPageSetupPS(wxCommandEvent& event);
 #endif
+#ifdef __WXMAC__
+    void OnPageMargins(wxCommandEvent& event);
+#endif
 
     void OnExit(wxCommandEvent& event);
     void OnPrintAbout(wxCommandEvent& event);
@@ -74,8 +78,10 @@ class MyPrintout: public wxPrintout
   bool OnBeginDocument(int startPage, int endPage);
   void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo);
 
-  void DrawPageOne(wxDC *dc);
-  void DrawPageTwo(wxDC *dc);
+  void DrawPageOne();
+
+  void DrawPageTwo();
+
 };
 
 #define WXPRINT_QUIT            100
@@ -91,3 +97,7 @@ class MyPrintout: public wxPrintout
 
 #define WXPRINT_ANGLEUP         110
 #define WXPRINT_ANGLEDOWN       111
+
+#ifdef __WXMAC__
+    #define WXPRINT_PAGE_MARGINS 112
+#endif
diff --git a/src/common/prntbase.cpp b/src/common/prntbase.cpp
index bb8d65092b..3b7a963959 100644
--- a/src/common/prntbase.cpp
+++ b/src/common/prntbase.cpp
@@ -566,6 +566,219 @@ void wxPrintout::GetPageInfo(int *minPage, int *maxPage, int *fromPage, int *toP
     *toPage = 1;
 }
 
+void wxPrintout::FitThisSizeToPaper(const wxSize& imageSize)
+{
+    // Set the DC scale and origin so that the given image size fits within the
+    // entire page and the origin is at the top left corner of the page. Note
+    // that with most printers, portions of the page will be non-printable. Use
+    // this if you're managing your own page margins.
+    if (!m_printoutDC) return;
+    wxRect paperRect = GetPaperRectPixels();
+    wxCoord pw, ph;
+    GetPageSizePixels(&pw, &ph);
+    wxCoord w, h;
+    m_printoutDC->GetSize(&w, &h);
+    float scaleX = ((float(paperRect.width) * w) / (float(pw) * imageSize.x));
+    float scaleY = ((float(paperRect.height) * h) / (float(ph) * imageSize.y));
+    float actualScale = wxMin(scaleX, scaleY);
+    m_printoutDC->SetUserScale(actualScale, actualScale); 
+    m_printoutDC->SetDeviceOrigin(0, 0);
+    wxRect logicalPaperRect = GetLogicalPaperRect();
+    SetLogicalOrigin(logicalPaperRect.x, logicalPaperRect.y);
+}
+
+void wxPrintout::FitThisSizeToPage(const wxSize& imageSize)
+{
+    // Set the DC scale and origin so that the given image size fits within the
+    // printable area of the page and the origin is at the top left corner of
+    // the printable area.
+    if (!m_printoutDC) return;
+    int w, h;
+    m_printoutDC->GetSize(&w, &h);
+    float scaleX = float(w) / imageSize.x;
+    float scaleY = float(h) / imageSize.y;
+    float actualScale = wxMin(scaleX, scaleY);
+    m_printoutDC->SetUserScale(actualScale, actualScale); 
+    m_printoutDC->SetDeviceOrigin(0, 0);
+}
+
+void wxPrintout::FitThisSizeToPageMargins(const wxSize& imageSize, const wxPageSetupDialogData& pageSetupData)
+{
+    // Set the DC scale and origin so that the given image size fits within the
+    // page margins defined in the given wxPageSetupDialogData object and the
+    // origin is at the top left corner of the page margins.
+    if (!m_printoutDC) return;
+    wxRect paperRect = GetPaperRectPixels();
+    wxCoord pw, ph;
+    GetPageSizePixels(&pw, &ph);
+    wxPoint topLeft = pageSetupData.GetMarginTopLeft();
+    wxPoint bottomRight = pageSetupData.GetMarginBottomRight();
+    wxCoord mw, mh;
+    GetPageSizeMM(&mw, &mh);
+    float mmToDeviceX = float(pw) / mw;
+    float mmToDeviceY = float(ph) / mh;
+    wxRect pageMarginsRect(paperRect.x + wxCoord(mmToDeviceX * topLeft.x),
+        paperRect.y + wxCoord(mmToDeviceY * topLeft.y),
+        paperRect.width - wxCoord(mmToDeviceX * (topLeft.x + bottomRight.x)),
+        paperRect.height - wxCoord(mmToDeviceY * (topLeft.y + bottomRight.y)));
+    wxCoord w, h;
+    m_printoutDC->GetSize(&w, &h);
+    float scaleX = (float(pageMarginsRect.width) * w) / (float(pw) * imageSize.x);
+    float scaleY = (float(pageMarginsRect.height) * h) / (float(ph) * imageSize.y);
+    float actualScale = wxMin(scaleX, scaleY);
+    m_printoutDC->SetUserScale(actualScale, actualScale); 
+    m_printoutDC->SetDeviceOrigin(0, 0);
+    wxRect logicalPageMarginsRect = GetLogicalPageMarginsRect(pageSetupData);
+    SetLogicalOrigin(logicalPageMarginsRect.x, logicalPageMarginsRect.y);
+}
+
+void wxPrintout::MapScreenSizeToPaper()
+{
+    // Set the DC scale so that an image on the screen is the same size on the
+    // paper and the origin is at the top left of the paper. Note that with most
+    // printers, portions of the page will be cut off. Use this if you're
+    // managing your own page margins.
+    if (!m_printoutDC) return;
+    MapScreenSizeToPage();
+    wxRect logicalPaperRect = GetLogicalPaperRect();
+    SetLogicalOrigin(logicalPaperRect.x, logicalPaperRect.y);
+}
+
+void wxPrintout::MapScreenSizeToPage()
+{
+    // Set the DC scale and origin so that an image on the screen is the same
+    // size on the paper and the origin is at the top left of the printable area.
+    if (!m_printoutDC) return;
+    int ppiScreenX, ppiScreenY; 
+    GetPPIScreen(&ppiScreenX, &ppiScreenY); 
+    int ppiPrinterX, ppiPrinterY; 
+    GetPPIPrinter(&ppiPrinterX, &ppiPrinterY); 
+    int w, h; 
+    m_printoutDC->GetSize(&w, &h); 
+    int pageSizePixelsX, pageSizePixelsY; 
+    GetPageSizePixels(&pageSizePixelsX, &pageSizePixelsY); 
+    float userScaleX = (float(ppiPrinterX) * w) / (float(ppiScreenX) * pageSizePixelsX); 
+    float userScaleY = (float(ppiPrinterY) * h) / (float(ppiScreenY) * pageSizePixelsY); 
+    m_printoutDC->SetUserScale(userScaleX, userScaleY);
+    m_printoutDC->SetDeviceOrigin(0, 0);
+}
+
+void wxPrintout::MapScreenSizeToPageMargins(const wxPageSetupDialogData& pageSetupData)
+{
+    // Set the DC scale so that an image on the screen is the same size on the
+    // paper and the origin is at the top left of the page margins defined by
+    // the given wxPageSetupDialogData object.
+    if (!m_printoutDC) return;
+    MapScreenSizeToPage();
+    wxRect logicalPageMarginsRect = GetLogicalPageMarginsRect(pageSetupData);
+    SetLogicalOrigin(logicalPageMarginsRect.x, logicalPageMarginsRect.y);
+}
+
+void wxPrintout::MapScreenSizeToDevice()
+{
+    // Set the DC scale so that a screen pixel is the same size as a device
+    // pixel and the origin is at the top left of the printable area.
+    if (!m_printoutDC) return;
+    int w, h; 
+    m_printoutDC->GetSize(&w, &h); 
+    int pageSizePixelsX, pageSizePixelsY; 
+    GetPageSizePixels(&pageSizePixelsX, &pageSizePixelsY); 
+    float userScaleX = float(w) / pageSizePixelsX; 
+    float userScaleY = float(h) / pageSizePixelsY; 
+    m_printoutDC->SetUserScale(userScaleX, userScaleY);
+    m_printoutDC->SetDeviceOrigin(0, 0);
+}
+
+wxRect wxPrintout::GetLogicalPaperRect() const
+{
+    // Return the rectangle in logical units that corresponds to the paper
+    // rectangle.
+    wxRect paperRect = GetPaperRectPixels();
+    wxCoord pw, ph;
+    GetPageSizePixels(&pw, &ph);
+    wxCoord w, h;
+    m_printoutDC->GetSize(&w, &h);
+    if (w == pw && h == ph) {
+        // this DC matches the printed page, so no scaling
+        return wxRect(m_printoutDC->DeviceToLogicalX(paperRect.x), 
+            m_printoutDC->DeviceToLogicalY(paperRect.y), 
+            m_printoutDC->DeviceToLogicalXRel(paperRect.width), 
+            m_printoutDC->DeviceToLogicalYRel(paperRect.height));
+    }
+    // This DC doesn't match the printed page, so we have to scale.
+    float scaleX = float(w) / pw;
+    float scaleY = float(h) / ph;
+    return wxRect(m_printoutDC->DeviceToLogicalX(wxCoord(paperRect.x * scaleX)), 
+        m_printoutDC->DeviceToLogicalY(wxCoord(paperRect.y * scaleY)), 
+        m_printoutDC->DeviceToLogicalXRel(wxCoord(paperRect.width * scaleX)), 
+        m_printoutDC->DeviceToLogicalYRel(wxCoord(paperRect.height * scaleY)));
+}
+
+wxRect wxPrintout::GetLogicalPageRect() const
+{
+    // Return the rectangle in logical units that corresponds to the printable
+    // area.
+    int w, h;
+    m_printoutDC->GetSize(&w, &h);
+    return wxRect(m_printoutDC->DeviceToLogicalX(0), 
+        m_printoutDC->DeviceToLogicalY(0), 
+        m_printoutDC->DeviceToLogicalXRel(w), 
+        m_printoutDC->DeviceToLogicalYRel(h));
+}
+
+wxRect wxPrintout::GetLogicalPageMarginsRect(const wxPageSetupDialogData& pageSetupData) const
+{
+    // Return the rectangle in logical units that corresponds to the region
+    // within the page margins as specified by the given wxPageSetupDialogData
+    // object.
+    wxRect paperRect = GetPaperRectPixels();
+    wxCoord pw, ph;
+    GetPageSizePixels(&pw, &ph);
+    wxPoint topLeft = pageSetupData.GetMarginTopLeft();
+    wxPoint bottomRight = pageSetupData.GetMarginBottomRight();
+    wxCoord mw, mh;
+    GetPageSizeMM(&mw, &mh);
+    float mmToDeviceX = float(pw) / mw;
+    float mmToDeviceY = float(ph) / mh;
+    wxRect pageMarginsRect(paperRect.x + wxCoord(mmToDeviceX * topLeft.x),
+        paperRect.y + wxCoord(mmToDeviceY * topLeft.y),
+        paperRect.width - wxCoord(mmToDeviceX * (topLeft.x + bottomRight.x)),
+        paperRect.height - wxCoord(mmToDeviceY * (topLeft.y + bottomRight.y)));
+    wxCoord w, h;
+    m_printoutDC->GetSize(&w, &h);
+    if (w == pw && h == ph) {
+        // this DC matches the printed page, so no scaling
+        return wxRect(m_printoutDC->DeviceToLogicalX(pageMarginsRect.x), 
+            m_printoutDC->DeviceToLogicalY(pageMarginsRect.y), 
+            m_printoutDC->DeviceToLogicalXRel(pageMarginsRect.width), 
+            m_printoutDC->DeviceToLogicalYRel(pageMarginsRect.height));
+    }
+    // This DC doesn't match the printed page, so we have to scale.
+    float scaleX = float(w) / pw;
+    float scaleY = float(h) / ph;
+    return wxRect(m_printoutDC->DeviceToLogicalX(wxCoord(pageMarginsRect.x * scaleX)), 
+        m_printoutDC->DeviceToLogicalY(wxCoord(pageMarginsRect.y * scaleY)), 
+        m_printoutDC->DeviceToLogicalXRel(wxCoord(pageMarginsRect.width * scaleX)), 
+        m_printoutDC->DeviceToLogicalYRel(wxCoord(pageMarginsRect.height * scaleY)));
+}
+
+void wxPrintout::SetLogicalOrigin(wxCoord x, wxCoord y)
+{
+    // Set the device origin by specifying a point in logical coordinates.
+    m_printoutDC->SetDeviceOrigin(m_printoutDC->LogicalToDeviceX(x), 
+        m_printoutDC->LogicalToDeviceY(y));
+}
+    
+void wxPrintout::OffsetLogicalOrigin(wxCoord xoff, wxCoord yoff)
+{
+    // Offset the device origin by a specified distance in device coordinates.
+    wxCoord x = m_printoutDC->LogicalToDeviceX(0);
+    wxCoord y = m_printoutDC->LogicalToDeviceY(0);
+    m_printoutDC->SetDeviceOrigin(x + m_printoutDC->LogicalToDeviceXRel(xoff), 
+        y + m_printoutDC->LogicalToDeviceYRel(yoff));
+}
+    
+
 //----------------------------------------------------------------------------
 // wxPreviewCanvas
 //----------------------------------------------------------------------------
@@ -1177,6 +1390,39 @@ wxFrame *wxPrintPreviewBase::GetFrame() const
 wxPreviewCanvas *wxPrintPreviewBase::GetCanvas() const
     { return m_previewCanvas; }
 
+void wxPrintPreviewBase::CalcRects(wxPreviewCanvas *canvas, wxRect& pageRect, wxRect& paperRect)
+{
+    // Calculate the rectangles for the printable area of the page and the
+    // entire paper as they appear on the canvas on-screen.
+    int canvasWidth, canvasHeight;
+    canvas->GetSize(&canvasWidth, &canvasHeight);
+
+    float zoomScale = float(m_currentZoom) / 100;
+    float screenPrintableWidth = zoomScale * m_pageWidth * m_previewScaleX;
+    float screenPrintableHeight = zoomScale * m_pageHeight * m_previewScaleY;
+
+    wxRect devicePaperRect = m_previewPrintout->GetPaperRectPixels();
+    wxCoord devicePrintableWidth, devicePrintableHeight;
+    m_previewPrintout->GetPageSizePixels(&devicePrintableWidth, &devicePrintableHeight);
+    float scaleX = screenPrintableWidth / devicePrintableWidth;
+    float scaleY = screenPrintableHeight / devicePrintableHeight;
+    paperRect.width = wxCoord(scaleX * devicePaperRect.width);
+    paperRect.height = wxCoord(scaleY * devicePaperRect.height);
+
+    paperRect.x = wxCoord((canvasWidth - paperRect.width)/ 2.0);
+    if (paperRect.x < m_leftMargin)
+        paperRect.x = m_leftMargin;
+    paperRect.y = wxCoord((canvasHeight - paperRect.height)/ 2.0);
+    if (paperRect.y < m_topMargin)
+        paperRect.y = m_topMargin;
+
+    pageRect.x = paperRect.x - wxCoord(scaleX * devicePaperRect.x);
+    pageRect.y = paperRect.y - wxCoord(scaleY * devicePaperRect.y);
+    pageRect.width = wxCoord(screenPrintableWidth);
+    pageRect.height = wxCoord(screenPrintableHeight);
+}
+
+
 bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
 {
     DrawBlankPage(canvas, dc);
@@ -1184,32 +1430,20 @@ bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
     if (!m_previewBitmap)
         if (!RenderPage(m_currentPage))
             return false;
-
     if (!m_previewBitmap)
         return false;
-
     if (!canvas)
         return false;
 
-    int canvasWidth, canvasHeight;
-    canvas->GetSize(&canvasWidth, &canvasHeight);
-
-    double zoomScale = ((float)m_currentZoom/(float)100);
-    double actualWidth = (zoomScale*m_pageWidth*m_previewScale);
-    //  float actualHeight = (float)(zoomScale*m_pageHeight*m_previewScale);
-
-    int x = (int) ((canvasWidth - actualWidth)/2.0);
-    if (x < m_leftMargin)
-        x = m_leftMargin;
-    int y = m_topMargin;
-
+    wxRect pageRect, paperRect;
+    CalcRects(canvas, pageRect, paperRect);
     wxMemoryDC temp_dc;
     temp_dc.SelectObject(*m_previewBitmap);
 
-    dc.Blit(x, y, m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
+    dc.Blit(pageRect.x, pageRect.y, 
+        m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
 
     temp_dc.SelectObject(wxNullBitmap);
-
     return true;
 }
 
@@ -1219,18 +1453,12 @@ void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas *canvas)
     if (!canvas)
         return ;
 
-    int canvasWidth, canvasHeight;
-    canvas->GetSize(&canvasWidth, &canvasHeight);
-
-    double zoomScale = ((float)m_currentZoom/(float)100);
-    double actualWidth = (zoomScale*m_pageWidth*m_previewScale);
-    double actualHeight = (zoomScale*m_pageHeight*m_previewScale);
-
-    // Set the scrollbars appropriately
-    int totalWidth = (int)(actualWidth + 2*m_leftMargin);
-    int totalHeight = (int)(actualHeight + 2*m_topMargin);
-    int scrollUnitsX = totalWidth/10;
-    int scrollUnitsY = totalHeight/10;
+    wxRect pageRect, paperRect;
+    CalcRects(canvas, pageRect, paperRect);
+     int totalWidth = paperRect.width + 2 * m_leftMargin;
+    int totalHeight = paperRect.height + 2 * m_topMargin;
+    int scrollUnitsX = totalWidth / 10;
+    int scrollUnitsY = totalHeight / 10;
     wxSize virtualSize = canvas->GetVirtualSize();
     if (virtualSize.GetWidth() != totalWidth || virtualSize.GetHeight() != totalHeight)
         canvas->SetScrollbars(10, 10, scrollUnitsX, scrollUnitsY, 0, 0, true);
@@ -1240,23 +1468,19 @@ bool wxPrintPreviewBase::RenderPage(int pageNum)
 {
     wxBusyCursor busy;
 
-    int canvasWidth, canvasHeight;
-
     if (!m_previewCanvas)
     {
         wxFAIL_MSG(_T("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
-
         return false;
     }
-    m_previewCanvas->GetSize(&canvasWidth, &canvasHeight);
 
-    double zoomScale = (m_currentZoom/100.0);
-    int actualWidth = (int)(zoomScale*m_pageWidth*m_previewScale);
-    int actualHeight = (int)(zoomScale*m_pageHeight*m_previewScale);
+    wxRect pageRect, paperRect;
+    CalcRects(m_previewCanvas, pageRect, paperRect);
 
     if (!m_previewBitmap)
     {
-        m_previewBitmap = new wxBitmap((int)actualWidth, (int)actualHeight);
+        m_previewBitmap = new wxBitmap(pageRect.width, pageRect.height);
+
         if (!m_previewBitmap || !m_previewBitmap->Ok())
         {
             if (m_previewBitmap) {
@@ -1320,43 +1544,28 @@ bool wxPrintPreviewBase::RenderPage(int pageNum)
     return true;
 }
 
-
 bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
 {
-    int canvasWidth, canvasHeight;
-    canvas->GetSize(&canvasWidth, &canvasHeight);
+    wxRect pageRect, paperRect;
 
-    float zoomScale = (float)((float)m_currentZoom/(float)100);
-    float actualWidth = zoomScale*m_pageWidth*m_previewScale;
-    float actualHeight = zoomScale*m_pageHeight*m_previewScale;
+    CalcRects(canvas, pageRect, paperRect);
 
-    float x = (float)((canvasWidth - actualWidth)/2.0);
-    if (x < m_leftMargin)
-        x = (float)m_leftMargin;
-    float y = (float)m_topMargin;
+    // Draw shadow, allowing for 1-pixel border AROUND the actual paper
+    wxCoord shadowOffset = 4;
 
-    // Draw shadow, allowing for 1-pixel border AROUND the actual page
-    int shadowOffset = 4;
     dc.SetPen(*wxBLACK_PEN);
     dc.SetBrush(*wxBLACK_BRUSH);
-    /*
-    dc.DrawRectangle((int)(x-1 + shadowOffset), (int)(y-1 + shadowOffset), (int)(actualWidth+2), (int)(actualHeight+2));
-    */
-    dc.DrawRectangle((int)(x + shadowOffset), (int)(y + actualHeight+1), (int)(actualWidth), shadowOffset);
-    dc.DrawRectangle((int)(x + actualWidth), (int)(y + shadowOffset), shadowOffset, (int)(actualHeight));
+    dc.DrawRectangle(paperRect.x + shadowOffset, paperRect.y + paperRect.height + 1,
+        paperRect.width, shadowOffset);
+
+    dc.DrawRectangle(paperRect.x + paperRect.width, paperRect.y + shadowOffset,
+        shadowOffset, paperRect.height);
 
-    // Draw blank page allowing for 1-pixel border AROUND the actual page
+    // Draw blank page allowing for 1-pixel border AROUND the actual paper
     dc.SetPen(*wxBLACK_PEN);
     dc.SetBrush(*wxWHITE_BRUSH);
-
-    /*
-    wxRegion update_region = canvas->GetUpdateRegion();
-    wxRect r = update_region.GetBox();
-
-      printf( "x: %d y: %d w: %d h: %d.\n", (int)r.x, (int)r.y, (int)r.width, (int)r.height );
-    */
-
-    dc.DrawRectangle((int)(x-2), (int)(y-1), (int)(actualWidth+3), (int)(actualHeight+2));
+    dc.DrawRectangle(paperRect.x - 2, paperRect.y - 1, 
+        paperRect.width + 3, paperRect.height + 2);
 
     return true;
 }
@@ -1399,6 +1608,7 @@ bool wxPrintPreviewBase::IsOk() const
 { return m_isOk; }
 void wxPrintPreviewBase::SetOk(bool ok)
 { m_isOk = ok; }
+
 //----------------------------------------------------------------------------
 // wxPrintPreview
 //----------------------------------------------------------------------------
diff --git a/src/generic/printps.cpp b/src/generic/printps.cpp
index 18653aa45d..90cae631fb 100644
--- a/src/generic/printps.cpp
+++ b/src/generic/printps.cpp
@@ -122,8 +122,10 @@ bool wxPostScriptPrinter::Print(wxWindow *parent, wxPrintout *printout, bool pro
     int w, h;
     dc->GetSize(&w, &h);
     printout->SetPageSizePixels((int)w, (int)h);
-    dc->GetSizeMM(&w, &h);
-    printout->SetPageSizeMM((int)w, (int)h);
+    printout->SetPaperRectPixels(wxRect(0, 0, w, h));
+    int mw, mh;
+    dc->GetSizeMM(&mw, &mh);
+    printout->SetPageSizeMM((int)mw, (int)mh);
 
     // Create an abort window
     wxBeginBusyCursor();
@@ -349,18 +351,19 @@ void wxPostScriptPrintPreview::DetermineScaling()
             m_pageWidth = sizeDevUnits.y;
             m_pageHeight = sizeDevUnits.x;
             m_previewPrintout->SetPageSizeMM(sizeMM.y, sizeMM.x);
-            m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
         }
         else
         {
             m_pageWidth = sizeDevUnits.x;
             m_pageHeight = sizeDevUnits.y;
             m_previewPrintout->SetPageSizeMM(sizeMM.x, sizeMM.y);
-            m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
         }
+        m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
+        m_previewPrintout->SetPaperRectPixels(wxRect(0, 0, m_pageWidth, m_pageHeight));
 
         // At 100%, the page should look about page-size on the screen.
-        m_previewScale = (float)0.8 * 72.0 / (float)wxPostScriptDC::GetResolution();
+        m_previewScaleX = (float)0.8 * 72.0 / (float)wxPostScriptDC::GetResolution();
+        m_previewScaleY = m_previewScaleX;
     }
 }
 
diff --git a/src/gtk/gnome/gprint.cpp b/src/gtk/gnome/gprint.cpp
index 0e14a5ca39..0d12dfa502 100644
--- a/src/gtk/gnome/gprint.cpp
+++ b/src/gtk/gnome/gprint.cpp
@@ -732,8 +732,10 @@ bool wxGnomePrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt )
     int w, h;
     dc->GetSize(&w, &h);
     printout->SetPageSizePixels((int)w, (int)h);
-    dc->GetSizeMM(&w, &h);
-    printout->SetPageSizeMM((int)w, (int)h);
+    printout->SetPaperRectPixels(wxRect(0, 0, w, h));
+    int mw, mh;
+    dc->GetSizeMM(&mw, &mh);
+    printout->SetPageSizeMM((int)mw, (int)mh);
 
     printout->OnPreparePrinting();
 
@@ -1946,18 +1948,19 @@ void wxGnomePrintPreview::DetermineScaling()
             m_pageWidth = sizeDevUnits.y;
             m_pageHeight = sizeDevUnits.x;
             m_previewPrintout->SetPageSizeMM(sizeMM.y, sizeMM.x);
-            m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
         }
         else
         {
             m_pageWidth = sizeDevUnits.x;
             m_pageHeight = sizeDevUnits.y;
             m_previewPrintout->SetPageSizeMM(sizeMM.x, sizeMM.y);
-            m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
         }
+        m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
+        m_previewPrintout->SetPaperRectPixels(wxRect(0, 0, m_pageWidth, m_pageHeight));
 
         // At 100%, the page should look about page-size on the screen.
-        m_previewScale = (float)0.8 * 72.0 / (float)wxGnomePrintDC::GetResolution();
+        m_previewScaleX = (float)0.8 * 72.0 / (float)wxGnomePrintDC::GetResolution();
+        m_previewScaleY = m_previewScaleX;
     }
 }
 
diff --git a/src/mac/carbon/dcprint.cpp b/src/mac/carbon/dcprint.cpp
index ad07cc2d94..fc24e02e66 100644
--- a/src/mac/carbon/dcprint.cpp
+++ b/src/mac/carbon/dcprint.cpp
@@ -359,6 +359,21 @@ void wxPrinterDC::EndDoc(void)
     }
 }
 
+wxRect wxPrinterDC::GetPaperRect()
+{
+    wxCoord w, h;
+    GetSize(&w, &h);
+    wxRect pageRect(0, 0, w, h);
+    wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) m_printData.GetNativeData() ;
+    OSStatus err = noErr ;
+    PMRect rPaper;
+    err = PMGetAdjustedPaperRect(native->m_macPageFormat, &rPaper);
+    if ( err != noErr )
+        return pageRect;
+    return wxRect(wxCoord(rPaper.left), wxCoord(rPaper.top),
+        wxCoord(rPaper.right - rPaper.left), wxCoord(rPaper.bottom - rPaper.top));
+}
+
 void wxPrinterDC::StartPage(void)
 {
     if ( !m_ok )
diff --git a/src/mac/carbon/printdlg.cpp b/src/mac/carbon/printdlg.cpp
index 598f4e733e..f4e163b3ed 100644
--- a/src/mac/carbon/printdlg.cpp
+++ b/src/mac/carbon/printdlg.cpp
@@ -23,6 +23,7 @@
 
 #include "wx/mac/printdlg.h"
 #include "wx/mac/private/print.h"
+#include "wx/statline.h"
 
 
 // Use generic page setup dialog: use your own native one if one exists.
@@ -116,20 +117,20 @@ int wxMacPrintDialog::ShowModal()
     return result;
 }
 
-wxDC * wxMacPrintDialog::GetPrintDC()
+wxDC *wxMacPrintDialog::GetPrintDC()
 {
     return new wxPrinterDC( m_printDialogData.GetPrintData() );
 }
 
 IMPLEMENT_CLASS(wxMacPageSetupDialog, wxPageSetupDialogBase)
 
-wxMacPageSetupDialog::wxMacPageSetupDialog( wxWindow *p, wxPageSetupDialogData *data )
+wxMacPageSetupDialog::wxMacPageSetupDialog( wxWindow *p, wxPageSetupData *data )
     : wxPageSetupDialogBase()
 {
     Create( p, data );
 }
 
-bool wxMacPageSetupDialog::Create( wxWindow *p, wxPageSetupDialogData *data )
+bool wxMacPageSetupDialog::Create( wxWindow *p, wxPageSetupData *data )
 {
     m_dialogParent = p;
 
@@ -194,4 +195,89 @@ int wxMacPageSetupDialog::ShowModal()
     return result;
 }
 
+
+IMPLEMENT_CLASS(wxMacPageMarginsDialog, wxDialog)
+
+wxMacPageMarginsDialog::wxMacPageMarginsDialog(wxFrame *parent, wxPageSetupData *data) :
+  wxDialog(parent, wxID_ANY, wxString(wxT("Page Margins"))),
+  m_pageSetupDialogData(data)
+  {
+  GetMinMargins();
+  wxBoxSizer *colSizer = new wxBoxSizer(wxVERTICAL);
+  wxFlexGridSizer *gridSizer = new wxFlexGridSizer(4, 5, 5);
+  colSizer->Add(gridSizer, wxSizerFlags().Border(wxALL, 5));
+  gridSizer->Add(new wxStaticText(this, wxID_ANY, wxT("Left (mm):")), wxSizerFlags().Right());
+  gridSizer->Add(m_LeftMargin = new wxTextCtrl(this, wxID_ANY), wxSizerFlags().Left());
+  gridSizer->Add(new wxStaticText(this, wxID_ANY, wxT("Top (mm):")), wxSizerFlags().Right());
+  gridSizer->Add(m_TopMargin = new wxTextCtrl(this, wxID_ANY), wxSizerFlags().Left());
+  gridSizer->Add(new wxStaticText(this, wxID_ANY, wxT("Right (mm):")), wxSizerFlags().Right());
+  gridSizer->Add(m_RightMargin = new wxTextCtrl(this, wxID_ANY), wxSizerFlags().Left());
+  gridSizer->Add(new wxStaticText(this, wxID_ANY, wxT("Bottom (mm):")), wxSizerFlags().Right());
+  gridSizer->Add(m_BottomMargin = new wxTextCtrl(this, wxID_ANY), wxSizerFlags().Left());
+  colSizer->Add(new wxStaticLine(this), wxSizerFlags().Expand().Border(wxTOP|wxBOTTOM, 5));
+  colSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Expand().Border(wxALL, 5));
+  TransferToWindow();
+  SetSizerAndFit(colSizer);
+  Center(wxBOTH);
+  }
+
+bool wxMacPageMarginsDialog::TransferToWindow()
+  {
+  wxASSERT(m_pageSetupDialogData);
+  wxPoint topLeft = m_pageSetupDialogData->GetMarginTopLeft();
+  wxPoint bottomRight = m_pageSetupDialogData->GetMarginBottomRight();
+  wxPoint minTopLeft = m_pageSetupDialogData->GetMinMarginTopLeft();
+  wxPoint minBottomRight = m_pageSetupDialogData->GetMinMarginBottomRight();
+  m_LeftMargin->SetValue(wxString::Format(wxT("%d"), wxMax(topLeft.x, minTopLeft.x)));
+  m_LeftMargin->SetSelection(-1, -1);
+  m_TopMargin->SetValue(wxString::Format(wxT("%d"), wxMax(topLeft.y, minTopLeft.y)));
+  m_TopMargin->SetSelection(-1, -1);
+  m_RightMargin->SetValue(wxString::Format(wxT("%d"), wxMax(bottomRight.x, minBottomRight.x)));
+  m_RightMargin->SetSelection(-1, -1);
+  m_BottomMargin->SetValue(wxString::Format(wxT("%d"), wxMax(bottomRight.y, minBottomRight.y)));
+  m_BottomMargin->SetSelection(-1, -1);
+  m_LeftMargin->SetFocus();
+  return true;
+  }
+  
+bool wxMacPageMarginsDialog::TransferDataFromWindow()
+  {
+  wxPoint topLeft, bottomRight;
+  if (!CheckValue(m_LeftMargin, &topLeft.x, m_MinMarginTopLeft.x, wxT("left margin"))) return false;
+  if (!CheckValue(m_TopMargin, &topLeft.y, m_MinMarginTopLeft.y, wxT("top margin"))) return false;
+  if (!CheckValue(m_RightMargin, &bottomRight.x, m_MinMarginBottomRight.x, wxT("right margin"))) return false;
+  if (!CheckValue(m_BottomMargin, &bottomRight.y, m_MinMarginBottomRight.y, wxT("bottom margin"))) return false;
+  m_pageSetupDialogData->SetMarginTopLeft(topLeft);
+  m_pageSetupDialogData->SetMarginBottomRight(bottomRight);
+  return true;
+  }
+  
+bool wxMacPageMarginsDialog::CheckValue(wxTextCtrl* textCtrl, int *value, int minValue, const wxString& name)
+  {
+  long lvalue;
+  if (!textCtrl->GetValue().ToLong(&lvalue))
+    {
+    wxMessageBox(wxString::Format(wxT("Sorry, \"%s\" is not a valid numerical value for the %s"), textCtrl->GetValue().c_str(), name.c_str()), wxT("Page Margin Error"));
+    return false;
+    }
+  if (lvalue < minValue)
+    {
+    wxMessageBox(wxString::Format(wxT("Sorry, \"%s\" is not a valid value for the %s, which must be >= %d"), textCtrl->GetValue().c_str(), name.c_str(), minValue), wxT("Page Margin Error"));
+    textCtrl->SetValue(wxString::Format(wxT("%d"), minValue));
+    textCtrl->SetSelection(-1, -1);
+    textCtrl->SetFocus();
+    return false;
+    }
+  *value = int(lvalue);
+  return true;
+  }
+
+void wxMacPageMarginsDialog::GetMinMargins()
+  {
+  m_MinMarginTopLeft = m_pageSetupDialogData->GetMinMarginTopLeft();
+  m_MinMarginBottomRight = m_pageSetupDialogData->GetMinMarginBottomRight();
+  }
+
+
+
 #endif
diff --git a/src/mac/carbon/printmac.cpp b/src/mac/carbon/printmac.cpp
index 9d695cd4d2..6df266562e 100644
--- a/src/mac/carbon/printmac.cpp
+++ b/src/mac/carbon/printmac.cpp
@@ -334,13 +334,14 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
         m_printDialogData.SetMaxPage(9999);
 
     // Create a suitable device context
-    wxDC *dc = NULL;
+    wxPrinterDC *dc = NULL;
     if (prompt)
     {
-        wxPrintDialog dialog(parent, & m_printDialogData);
+        wxMacPrintDialog dialog(parent, & m_printDialogData);
         if (dialog.ShowModal() == wxID_OK)
         {
-            dc = dialog.GetPrintDC();
+            dc = wxDynamicCast(dialog.GetPrintDC(), wxPrinterDC);
+            wxASSERT(dc);
             m_printDialogData = dialog.GetPrintDialogData();
         }
     }
@@ -375,11 +376,12 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
     printout->SetDC(dc);
 
     int w, h;
-    wxCoord ww, hh;
     dc->GetSize(&w, &h);
     printout->SetPageSizePixels((int)w, (int)h);
-    dc->GetSizeMM(&ww, &hh);
-    printout->SetPageSizeMM((int)ww, (int)hh);
+    printout->SetPaperRectPixels(dc->GetPaperRect());
+    wxCoord mw, mh;
+    dc->GetSizeMM(&mw, &mh);
+    printout->SetPageSizeMM((int)mw, (int)mh);
 
     // Create an abort window
     wxBeginBusyCursor();
@@ -555,36 +557,43 @@ void wxMacPrintPreview::DetermineScaling(void)
     wxSize ppiScreen( 72 , 72 ) ;
     wxSize ppiPrinter( 72 , 72 ) ;
     
+    // Note that with Leopard, screen dpi=72 is no longer a given
     m_previewPrintout->SetPPIScreen( ppiScreen.x , ppiScreen.y ) ;
     
-    int x , y ;
+    wxCoord w , h ;
     wxCoord ww, hh;
+    wxRect paperRect;
 
     // Get a device context for the currently selected printer
     wxPrinterDC printerDC(m_printDialogData.GetPrintData());
     if (printerDC.Ok())
     {
         printerDC.GetSizeMM(&ww, &hh);
-        printerDC.GetSize( &x , &y ) ;
+        printerDC.GetSize( &w , &h ) ;
         ppiPrinter = printerDC.GetPPI() ;
+        paperRect = printerDC.GetPaperRect();
         m_isOk = true ;
     }
     else
     {
         // use some defaults
-        x = 8 * 72 ;
-        y = 11 * 72 ;
-        ww = (int) (x * 25.4 / ppiPrinter.x) ;
-        hh = (int) (y * 25.4 / ppiPrinter.y) ;
+        w = 8 * 72 ;
+        h = 11 * 72 ;
+        ww = (wxCoord) (w * 25.4 / ppiPrinter.x) ;
+        hh = (wxCoord) (h * 25.4 / ppiPrinter.y) ;
+        paperRect = wxRect(0, 0, w, h);
         m_isOk = false ;
     }
-    m_previewPrintout->SetPageSizeMM((int)ww, (int)hh);
-    m_previewPrintout->SetPageSizePixels( x , y) ;
-    m_pageWidth = x ;
-    m_pageHeight = y ;
+    m_pageWidth = w;
+    m_pageHeight = h;
+    
+    m_previewPrintout->SetPageSizePixels(w , h) ;
+    m_previewPrintout->SetPageSizeMM(ww, hh);
+    m_previewPrintout->SetPaperRectPixels(paperRect);
     m_previewPrintout->SetPPIPrinter( ppiPrinter.x , ppiPrinter.y ) ;
 
-    m_previewScale = (float)((float)ppiScreen.x/(float)ppiPrinter.y);
+    m_previewScaleX = float(ppiScreen.x) / ppiPrinter.x;
+    m_previewScaleY = float(ppiScreen.y) / ppiPrinter.y;
 }
 
 #endif
diff --git a/src/mac/classic/dcprint.cpp b/src/mac/classic/dcprint.cpp
index 03f81738af..c67228b4ff 100644
--- a/src/mac/classic/dcprint.cpp
+++ b/src/mac/classic/dcprint.cpp
@@ -398,6 +398,18 @@ void wxPrinterDC::EndPage(void)
     m_ok = m_nativePrinterDC->Ok() ;
 }
 
+wxRect wxPrinterDC::GetPaperRect()
+{
+    wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) m_printData.GetNativeData() ;
+    OSStatus err = noErr ;
+    PMRect rPaper;
+    err = PMGetAdjustedPaperRect(native->m_macPageFormat, &rPaper);
+    if ( err != noErr )
+        return pageRect;
+    return wxRect(wxCoord(rPaper.left), wxCoord(rPaper.top),
+        wxCoord(rPaper.right - rPaper.left), wxCoord(rPaper.bottom - rPaper.top));
+}
+
 void wxPrinterDC::DoGetSize(int *width, int *height) const
 {
     wxCHECK_RET( m_ok , _T("GetSize() doesn't work without a valid wxPrinterDC") );
diff --git a/src/mac/classic/printdlg.cpp b/src/mac/classic/printdlg.cpp
index 5928041001..6c8efd6520 100644
--- a/src/mac/classic/printdlg.cpp
+++ b/src/mac/classic/printdlg.cpp
@@ -122,3 +122,86 @@ int wxPageSetupDialog::ShowModal()
 
     return result ;
 }
+
+
+IMPLEMENT_CLASS(wxMacPageMarginsDialog, wxDialog)
+
+wxMacPageMarginsDialog::wxMacPageMarginsDialog(wxFrame *parent, wxPageSetupData *data) :
+  wxDialog(parent, wxID_ANY, wxString(wxT("Page Margins"))),
+  m_pageSetupDialogData(data)
+  {
+  GetMinMargins();
+  wxBoxSizer *colSizer = new wxBoxSizer(wxVERTICAL);
+  wxFlexGridSizer *gridSizer = new wxFlexGridSizer(4, 5, 5);
+  colSizer->Add(gridSizer, wxSizerFlags().Border(wxALL, 5));
+  gridSizer->Add(new wxStaticText(this, wxID_ANY, wxT("Left (mm):")), wxSizerFlags().Right());
+  gridSizer->Add(m_LeftMargin = new wxTextCtrl(this, wxID_ANY), wxSizerFlags().Left());
+  gridSizer->Add(new wxStaticText(this, wxID_ANY, wxT("Top (mm):")), wxSizerFlags().Right());
+  gridSizer->Add(m_TopMargin = new wxTextCtrl(this, wxID_ANY), wxSizerFlags().Left());
+  gridSizer->Add(new wxStaticText(this, wxID_ANY, wxT("Right (mm):")), wxSizerFlags().Right());
+  gridSizer->Add(m_RightMargin = new wxTextCtrl(this, wxID_ANY), wxSizerFlags().Left());
+  gridSizer->Add(new wxStaticText(this, wxID_ANY, wxT("Bottom (mm):")), wxSizerFlags().Right());
+  gridSizer->Add(m_BottomMargin = new wxTextCtrl(this, wxID_ANY), wxSizerFlags().Left());
+  colSizer->Add(new wxStaticLine(this), wxSizerFlags().Expand().Border(wxTOP|wxBOTTOM, 5));
+  colSizer->Add(CreateButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Expand().Border(wxALL, 5));
+  TransferToWindow();
+  SetSizerAndFit(colSizer);
+  Center(wxBOTH);
+  }
+
+bool wxMacPageMarginsDialog::TransferToWindow()
+  {
+  wxASSERT(m_pageSetupDialogData);
+  wxPoint topLeft = m_pageSetupDialogData->GetMarginTopLeft();
+  wxPoint bottomRight = m_pageSetupDialogData->GetMarginBottomRight();
+  wxPoint minTopLeft = m_pageSetupDialogData->GetMinMarginTopLeft();
+  wxPoint minBottomRight = m_pageSetupDialogData->GetMinMarginBottomRight();
+  m_LeftMargin->SetValue(wxString::Format(wxT("%d"), wxMax(topLeft.x, minTopLeft.x)));
+  m_LeftMargin->SetSelection(-1, -1);
+  m_TopMargin->SetValue(wxString::Format(wxT("%d"), wxMax(topLeft.y, minTopLeft.y)));
+  m_TopMargin->SetSelection(-1, -1);
+  m_RightMargin->SetValue(wxString::Format(wxT("%d"), wxMax(bottomRight.x, minBottomRight.x)));
+  m_RightMargin->SetSelection(-1, -1);
+  m_BottomMargin->SetValue(wxString::Format(wxT("%d"), wxMax(bottomRight.y, minBottomRight.y)));
+  m_BottomMargin->SetSelection(-1, -1);
+  m_LeftMargin->SetFocus();
+  return true;
+  }
+  
+bool wxMacPageMarginsDialog::TransferDataFromWindow()
+  {
+  wxPoint topLeft, bottomRight;
+  if (!CheckValue(m_LeftMargin, &topLeft.x, m_MinMarginTopLeft.x, wxT("left margin"))) return false;
+  if (!CheckValue(m_TopMargin, &topLeft.y, m_MinMarginTopLeft.y, wxT("top margin"))) return false;
+  if (!CheckValue(m_RightMargin, &bottomRight.x, m_MinMarginBottomRight.x, wxT("right margin"))) return false;
+  if (!CheckValue(m_BottomMargin, &bottomRight.y, m_MinMarginBottomRight.y, wxT("bottom margin"))) return false;
+  m_pageSetupDialogData->SetMarginTopLeft(topLeft);
+  m_pageSetupDialogData->SetMarginBottomRight(bottomRight);
+  return true;
+  }
+  
+bool wxMacPageMarginsDialog::CheckValue(wxTextCtrl* textCtrl, int *value, int minValue, const wxString& name)
+  {
+  long lvalue;
+  if (!textCtrl->GetValue().ToLong(&lvalue))
+    {
+    wxMessageBox(wxString::Format(wxT("Sorry, \"%s\" is not a valid numerical value for the %s"), textCtrl->GetValue().c_str(), name.c_str()), wxT("Page Margin Error"));
+    return false;
+    }
+  if (lvalue < minValue)
+    {
+    wxMessageBox(wxString::Format(wxT("Sorry, \"%s\" is not a valid value for the %s, which must be >= %d"), textCtrl->GetValue().c_str(), name.c_str(), minValue), wxT("Page Margin Error"));
+    textCtrl->SetValue(wxString::Format(wxT("%d"), minValue));
+    textCtrl->SetSelection(-1, -1);
+    textCtrl->SetFocus();
+    return false;
+    }
+  *value = int(lvalue);
+  return true;
+  }
+
+void wxMacPageMarginsDialog::GetMinMargins()
+  {
+  m_MinMarginTopLeft = m_pageSetupDialogData->GetMinMarginTopLeft();
+  m_MinMarginBottomRight = m_pageSetupDialogData->GetMinMarginBottomRight();
+  }
diff --git a/src/mac/classic/printmac.cpp b/src/mac/classic/printmac.cpp
index bb70bd50e8..3f4cbef6a8 100644
--- a/src/mac/classic/printmac.cpp
+++ b/src/mac/classic/printmac.cpp
@@ -540,7 +540,7 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
         m_printDialogData.SetMaxPage(9999);
 
     // Create a suitable device context
-    wxDC *dc = NULL;
+    wxPrinterDC *dc = NULL;
     if (prompt)
     {
         wxPrintDialog dialog(parent, & m_printDialogData);
@@ -555,7 +555,6 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
         dc = new wxPrinterDC( m_printDialogData.GetPrintData() ) ;
     }
 
-
     // May have pressed cancel.
     if (!dc || !dc->Ok())
     {
@@ -564,7 +563,6 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
     }
 
     // on the mac we have always pixels as addressing mode with 72 dpi
-
     printout->SetPPIScreen(72, 72);
     printout->SetPPIPrinter(72, 72);
 
@@ -575,6 +573,7 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
     wxCoord ww, hh;
     dc->GetSize(&w, &h);
     printout->SetPageSizePixels((int)w, (int)h);
+    printout->SetPaperRectPixels(dc->GetPaperRect());
     dc->GetSizeMM(&ww, &hh);
     printout->SetPageSizeMM((int)ww, (int)hh);
 
@@ -742,35 +741,42 @@ void wxMacPrintPreview::DetermineScaling(void)
     int screenWidth , screenHeight ;
     wxDisplaySize( &screenWidth , &screenHeight ) ;
 
-    m_previewPrintout->SetPPIScreen( 72 , 72 ) ;
-    m_previewPrintout->SetPPIPrinter( 72 , 72 ) ;
-    m_previewPrintout->SetPageSizeMM( (int) (8.0 * 25.6), (int) (11.0 * 25.6) );
-    m_previewPrintout->SetPageSizePixels( 8 * 72 , 11 * 72 ) ;
-    m_pageWidth = 8 * 72 ;
-    m_pageHeight = 11 * 72 ;
-    m_previewScale = 1 ;
+    wxSize ppiScreen( 72 , 72 ) ;
+    wxSize ppiPrinter( 72 , 72 ) ;
+
+    m_previewPrintout->SetPPIScreen( ppiScreen.x , ppiScreen.y ) ;
+
+    wxCoord w , h ;
+    wxCoord ww, hh;
+    wxRect paperRect;
 
     // Get a device context for the currently selected printer
     wxPrinterDC printerDC(m_printDialogData.GetPrintData());
     if (printerDC.Ok())
     {
-        int x , y ;
-        wxCoord ww, hh;
         printerDC.GetSizeMM(&ww, &hh);
-        printerDC.GetSize( &x , &y ) ;
-        m_previewPrintout->SetPageSizeMM((int)ww, (int)hh);
-        m_previewPrintout->SetPageSizePixels( x , y) ;
-        m_pageWidth = x ;
-        m_pageHeight =  y ;
+        printerDC.GetSize( &w , &h ) ;
+        ppiPrinter = printerDC.GetPPI() ;
+        paperRect = printerDC.GetPaperRect();
         m_isOk = true ;
     }
     else
     {
+        // use some defaults
+        w = 8 * 72 ;
+        h = 11 * 72 ;
+        ww = (wxCoord) (w * 25.4 / ppiPrinter.x) ;
+        hh = (wxCoord) (h * 25.4 / ppiPrinter.y) ;
+        paperRect = wxRect(0, 0, w, h);
         m_isOk = false ;
     }
-    // At 100%, the page should look about page-size on the screen.
-    // m_previewScale = (float)((float)screenWidth/(float)printerWidth);
-    // m_previewScale = m_previewScale * (float)((float)screenXRes/(float)printerXRes);
+    m_previewPrintout->SetPageSizeMM(ww, hh);
+    m_previewPrintout->SetPageSizePixels(w , h) ;
+    m_previewPrintout->SetPaperRectPixels(paperRect);
+    m_pageWidth = w;
+    m_pageHeight = h;
+    m_previewPrintout->SetPPIPrinter( ppiPrinter.x , ppiPrinter.y ) ;
 
-    m_previewScale = 1 ;
+    m_previewScaleX = float(ppiScreen.x) / ppiPrinter.x;
+    m_previewScaleY = float(ppiScreen.y) / ppiPrinter.y;
 }
diff --git a/src/msw/dcprint.cpp b/src/msw/dcprint.cpp
index a2e365c072..32dad051fe 100644
--- a/src/msw/dcprint.cpp
+++ b/src/msw/dcprint.cpp
@@ -221,6 +221,19 @@ void wxPrinterDC::EndPage()
         ::EndPage((HDC) m_hDC);
 }
 
+
+wxRect wxPrinterDC::GetPaperRect()
+
+{
+    if (!Ok()) return wxRect(0, 0, 0, 0);
+    int w = ::GetDeviceCaps((HDC) m_hDC, PHYSICALWIDTH);
+    int h = ::GetDeviceCaps((HDC) m_hDC, PHYSICALHEIGHT);
+    int x = -::GetDeviceCaps((HDC) m_hDC, PHYSICALOFFSETX);
+    int y = -::GetDeviceCaps((HDC) m_hDC, PHYSICALOFFSETY);
+    return wxRect(x, y, w, h);
+}
+
+
 #if !wxUSE_PS_PRINTING
 
 // Returns default device and port names
diff --git a/src/msw/printdlg.cpp b/src/msw/printdlg.cpp
index ea57745e78..363e9302c6 100644
--- a/src/msw/printdlg.cpp
+++ b/src/msw/printdlg.cpp
@@ -647,7 +647,7 @@ wxDC *wxWindowsPrintDialog::GetPrintDC()
         return m_printerDC;
     }
     else
-        return (wxDC*) NULL;
+        return (wxPrinterDC*) NULL;
 }
 
 bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData &data )
diff --git a/src/msw/printwin.cpp b/src/msw/printwin.cpp
index 6856dd9462..2eadf2547f 100644
--- a/src/msw/printwin.cpp
+++ b/src/msw/printwin.cpp
@@ -42,7 +42,7 @@
 #endif
 
 #include "wx/msw/printwin.h"
-#include "wx/printdlg.h"
+#include "wx/msw/printdlg.h"	// RJL used Windows dialog?s
 #include "wx/msw/private.h"
 
 #include <stdlib.h>
@@ -106,10 +106,10 @@ bool wxWindowsPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt
         m_printDialogData.SetMaxPage(9999);
 
     // Create a suitable device context
-    wxDC *dc wxDUMMY_INITIALIZE(NULL);
+    wxPrinterDC *dc wxDUMMY_INITIALIZE(NULL);
     if (prompt)
     {
-        dc = PrintDialog(parent);
+        dc = wxDynamicCast(PrintDialog(parent), wxPrinterDC);
         if (!dc)
             return false;
     }
@@ -148,6 +148,7 @@ bool wxWindowsPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt
     int w, h;
     dc->GetSize(&w, &h);
     printout->SetPageSizePixels((int)w, (int)h);
+    printout->SetPaperRectPixels(dc->GetPaperRect());
 
     dc->GetSizeMM(&w, &h);
     printout->SetPageSizeMM((int)w, (int)h);
@@ -276,11 +277,11 @@ bool wxWindowsPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt
     return sm_lastError == wxPRINTER_NO_ERROR;
 }
 
-wxDC* wxWindowsPrinter::PrintDialog(wxWindow *parent)
+wxDC *wxWindowsPrinter::PrintDialog(wxWindow *parent)
 {
-    wxDC* dc = (wxDC*) NULL;
+    wxDC *dc = (wxPrinterDC*) NULL;
 
-    wxPrintDialog dialog(parent, & m_printDialogData);
+    wxWindowsPrintDialog dialog(parent, & m_printDialogData);
     int ret = dialog.ShowModal();
 
     if (ret == wxID_OK)
@@ -353,58 +354,65 @@ bool wxWindowsPrintPreview::Print(bool interactive)
 void wxWindowsPrintPreview::DetermineScaling()
 {
     ScreenHDC dc;
-    int screenWidth = ::GetDeviceCaps(dc, HORZSIZE);
-    int screenXRes = ::GetDeviceCaps(dc, HORZRES);
     int logPPIScreenX = ::GetDeviceCaps(dc, LOGPIXELSX);
     int logPPIScreenY = ::GetDeviceCaps(dc, LOGPIXELSY);
     m_previewPrintout->SetPPIScreen(logPPIScreenX, logPPIScreenY);
 
-
     // Get a device context for the currently selected printer
     wxPrinterDC printerDC(m_printDialogData.GetPrintData());
 
-    int printerWidth = 150;
-    int printerXRes = 1500;
-    int printerYRes = 2500;
+    int printerWidthMM;
+    int printerHeightMM;
+    int printerXRes;
+    int printerYRes;
+    int logPPIPrinterX;
+    int logPPIPrinterY;
+
+	wxRect paperRect;
 
     if ( printerDC.Ok() )
     {
         HDC dc = GetHdcOf(printerDC);
-
-        printerWidth = ::GetDeviceCaps(dc, HORZSIZE);
-        int printerHeight = ::GetDeviceCaps(dc, VERTSIZE);
+        printerWidthMM = ::GetDeviceCaps(dc, HORZSIZE);
+        printerHeightMM = ::GetDeviceCaps(dc, VERTSIZE);
         printerXRes = ::GetDeviceCaps(dc, HORZRES);
         printerYRes = ::GetDeviceCaps(dc, VERTRES);
+        logPPIPrinterX = ::GetDeviceCaps(dc, LOGPIXELSX);
+        logPPIPrinterY = ::GetDeviceCaps(dc, LOGPIXELSY);
 
-        int logPPIPrinterX = ::GetDeviceCaps(dc, LOGPIXELSX);
-        int logPPIPrinterY = ::GetDeviceCaps(dc, LOGPIXELSY);
-
-        m_previewPrintout->SetPPIPrinter(logPPIPrinterX, logPPIPrinterY);
-        m_previewPrintout->SetPageSizeMM(printerWidth, printerHeight);
+		paperRect = printerDC.GetPaperRect();
 
         if ( logPPIPrinterX == 0 ||
                 logPPIPrinterY == 0 ||
-                    printerWidth == 0 ||
-                        printerHeight == 0 )
+                    printerWidthMM == 0 ||
+                        printerHeightMM == 0 )
         {
             m_isOk = false;
         }
     }
     else
     {
+        // use some defaults
+        printerWidthMM = 150;
+        printerHeightMM = 250;
+        printerXRes = 1500;
+        printerYRes = 2500;
+        logPPIPrinterX = 600;
+        logPPIPrinterY = 600;
+
+		paperRect = wxRect(0, 0, printerXRes, printerYRes);
         m_isOk = false;
     }
-
     m_pageWidth = printerXRes;
     m_pageHeight = printerYRes;
+    m_previewPrintout->SetPageSizePixels(printerXRes, printerYRes);
+    m_previewPrintout->SetPageSizeMM(printerWidthMM, printerHeightMM);
+    m_previewPrintout->SetPaperRectPixels(paperRect);
+    m_previewPrintout->SetPPIPrinter(logPPIPrinterX, logPPIPrinterY);
 
     // At 100%, the page should look about page-size on the screen.
-    //
-    // TODO: the scale could be different in vertical and horizontal directions
-    float screenDPI = (float)screenXRes / screenWidth;
-    float printerDPI = (float)printerXRes / printerWidth;
-
-    m_previewScale = screenDPI / printerDPI;
+    m_previewScaleX = float(logPPIScreenX) / logPPIPrinterX;
+    m_previewScaleY = float(logPPIScreenY) / logPPIPrinterY;
 }
 
 /****************************************************************************
diff --git a/src/os2/dcprint.cpp b/src/os2/dcprint.cpp
index e71b9dc084..30ba0d7c3a 100644
--- a/src/os2/dcprint.cpp
+++ b/src/os2/dcprint.cpp
@@ -223,6 +223,15 @@ void wxPrinterDC::EndPage()
 //    if (m_hDC)
 //        ::EndPage((HDC) m_hDC);
 } // end of wxPrinterDC::EndPage
+
+wxRect wxPrinterDC::GetPaperRect()
+{
+    // Use page rect if we can't get paper rect.
+    wxCoord w, h;
+    GetSize(&w, &h);
+    return wxRect(0, 0, w, h);
+}
+
 #if 0
 // Returns default device and port names
 static bool wxGetDefaultDeviceName( wxString& rsDeviceName, wxString& rsPortName )
diff --git a/src/palmos/dcprint.cpp b/src/palmos/dcprint.cpp
index fae66da4eb..dc154f7b2f 100644
--- a/src/palmos/dcprint.cpp
+++ b/src/palmos/dcprint.cpp
@@ -100,6 +100,14 @@ void wxPrinterDC::EndPage()
 {
 }
 
+wxRect wxPrinterDC::GetPaperRect()
+{
+    // Use page rect if we can't get paper rect.
+    wxCoord w, h;
+    GetSize(&w, &h);
+    return wxRect(0, 0, w, h);
+}
+
 // Returns default device and port names
 static bool wxGetDefaultDeviceName(wxString& deviceName, wxString& portName)
 {
diff --git a/src/palmos/printpalm.cpp b/src/palmos/printpalm.cpp
index fdd9f8691b..27016dd926 100644
--- a/src/palmos/printpalm.cpp
+++ b/src/palmos/printpalm.cpp
@@ -118,6 +118,7 @@ bool wxPalmPrintPreview::Print(bool interactive)
 
 void wxPalmPrintPreview::DetermineScaling()
 {
+    // TODO
 }
 
 #endif
-- 
2.47.2

