]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/dcpsg.cpp
Border corrections
[wxWidgets.git] / src / generic / dcpsg.cpp
index 0a28ec92b6d8bcaad059ee71aa26942bab68b933..777796b782eb87640fae80d1118faec963e8a04d 100644 (file)
 #ifndef WX_PRECOMP
     #include "wx/intl.h"
     #include "wx/log.h"
-    #include "wx/app.h"
+    #include "wx/utils.h"
+    #include "wx/dcmemory.h"
+    #include "wx/math.h"
+    #include "wx/image.h"
+    #include "wx/icon.h"
 #endif // WX_PRECOMP
 
-#include "wx/dcmemory.h"
-#include "wx/utils.h"
-#include "wx/image.h"
 #include "wx/prntbase.h"
 #include "wx/generic/prntdlgg.h"
 #include "wx/paper.h"
 #include "wx/filefn.h"
-#include "wx/math.h"
 #include "wx/stdpaths.h"
 
 #ifdef __WXMSW__
@@ -235,22 +235,32 @@ static char wxPostScriptHeaderReencodeISO2[] =
 // wxPostScriptDC
 //-------------------------------------------------------------------------------
 
+// conversion
+static const double RAD2DEG  = 180.0 / M_PI;
+
+// we don't want to use only 72 dpi from PS print
+static const int DPI = 600;
+static const double PS2DEV = 600.0 / 72.0;
+static const double DEV2PS = 72.0 / 600.0;
+
+#define XLOG2DEV(x)     ((double)(LogicalToDeviceX(x)) * DEV2PS)
+#define XLOG2DEVREL(x)  ((double)(LogicalToDeviceXRel(x)) * DEV2PS)
+#define YLOG2DEV(x)     ((m_pageHeight - (double)LogicalToDeviceY(x)) * DEV2PS)
+#define YLOG2DEVREL(x)  ((double)(LogicalToDeviceYRel(x)) * DEV2PS)
+
 IMPLEMENT_DYNAMIC_CLASS(wxPostScriptDC, wxDC)
 
-float wxPostScriptDC::ms_PSScaleFactor = 1.0;
+//-------------------------------------------------------------------------------
 
-void wxPostScriptDC::SetResolution(int ppi)
+void wxPostScriptDC::SetResolution(int WXUNUSED(ppi))
 {
-    ms_PSScaleFactor = (float)ppi / 72.0;
 }
 
 int wxPostScriptDC::GetResolution()
 {
-    return (int)(ms_PSScaleFactor * 72.0);
+    return DPI;
 }
 
-//-------------------------------------------------------------------------------
-
 wxPostScriptDC::wxPostScriptDC ()
 {
     m_pstream = (FILE*) NULL;
@@ -266,8 +276,7 @@ wxPostScriptDC::wxPostScriptDC ()
     m_underlinePosition = 0.0;
     m_underlineThickness = 0.0;
 
-    m_signX =  1;  // default x-axis left to right
-    m_signY = -1;  // default y-axis bottom up -> top down
+    m_pageHeight = 842 * PS2DEV;
 }
 
 wxPostScriptDC::wxPostScriptDC (const wxPrintData& printData)
@@ -285,10 +294,9 @@ wxPostScriptDC::wxPostScriptDC (const wxPrintData& printData)
     m_underlinePosition = 0.0;
     m_underlineThickness = 0.0;
 
-    m_signX =  1;  // default x-axis left to right
-    m_signY = -1;  // default y-axis bottom up -> top down
-
-    m_printData = printData;
+    // this calculates m_pageHeight required for
+    // taking the inverted Y axis into account
+    SetPrintData( printData );
 
     m_ok = true;
 }
@@ -302,7 +310,7 @@ wxPostScriptDC::~wxPostScriptDC ()
     }
 }
 
-bool wxPostScriptDC::Ok() const
+bool wxPostScriptDC::IsOk() const
 {
   return m_ok;
 }
@@ -317,16 +325,20 @@ void wxPostScriptDC::DoSetClippingRegion (wxCoord x, wxCoord y, wxCoord w, wxCoo
 
     m_clipping = true;
 
-    PsPrintf( wxT("gsave\n newpath\n")
-              wxT("%d %d moveto\n")
-              wxT("%d %d lineto\n")
-              wxT("%d %d lineto\n")
-              wxT("%d %d lineto\n")
-              wxT("closepath clip newpath\n"),
-            LogicalToDeviceX(x),   LogicalToDeviceY(y),
-            LogicalToDeviceX(x+w), LogicalToDeviceY(y),
-            LogicalToDeviceX(x+w), LogicalToDeviceY(y+h),
-            LogicalToDeviceX(x),   LogicalToDeviceY(y+h) );
+    wxString buffer;
+    buffer.Printf( "gsave\n"
+                   "newpath\n"
+                   "%f %f moveto\n"
+                   "%f %f lineto\n"
+                   "%f %f lineto\n"
+                   "%f %f lineto\n"
+                   "closepath clip newpath\n",
+            XLOG2DEV(x),   YLOG2DEV(y),
+            XLOG2DEV(x+w), YLOG2DEV(y),
+            XLOG2DEV(x+w), YLOG2DEV(y+h),
+            XLOG2DEV(x),   YLOG2DEV(y+h) );
+    buffer.Replace( ",", "." );
+    PsPrint( buffer );
 }
 
 
@@ -375,26 +387,27 @@ void wxPostScriptDC::DoDrawLine (wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
 
     SetPen( m_pen );
 
-    PsPrintf( wxT("newpath\n")
-              wxT("%d %d moveto\n")
-              wxT("%d %d lineto\n")
-              wxT("stroke\n"),
-            LogicalToDeviceX(x1), LogicalToDeviceY(y1),
-            LogicalToDeviceX(x2), LogicalToDeviceY (y2) );
+    wxString buffer;
+    buffer.Printf( "newpath\n"
+                   "%f %f moveto\n"
+                   "%f %f lineto\n"
+                   "stroke\n",
+            XLOG2DEV(x1), YLOG2DEV(y1),
+            XLOG2DEV(x2), YLOG2DEV(y2) );
+    buffer.Replace( ",", "." );
+    PsPrint( buffer );
 
     CalcBoundingBox( x1, y1 );
     CalcBoundingBox( x2, y2 );
 }
 
-#define RAD2DEG 57.29577951308
-
 void wxPostScriptDC::DoDrawArc (wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc)
 {
     wxCHECK_RET( m_ok, wxT("invalid postscript dc") );
 
     wxCoord dx = x1 - xc;
     wxCoord dy = y1 - yc;
-    wxCoord radius = (wxCoord) sqrt( (double)(dx*dx+dy*dy) );
+    double radius = sqrt( (double)(dx*dx+dy*dy) );
     double alpha1, alpha2;
 
     if (x1 == x2 && y1 == y2)
@@ -421,36 +434,48 @@ void wxPostScriptDC::DoDrawArc (wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
     while (alpha1 > 360)  alpha1 -= 360; // 0 and 360 degree
     while (alpha2 > 360)  alpha2 -= 360;
 
+    int i_radius = wxRound( radius );
+
     if (m_brush.GetStyle() != wxTRANSPARENT)
     {
         SetBrush( m_brush );
 
-        PsPrintf( wxT("newpath\n")
-                  wxT("%d %d %d %d %d %d ellipse\n")
-                  wxT("%d %d lineto\n")
-                  wxT("closepath\n")
-                  wxT("fill\n"),
-                LogicalToDeviceX(xc), LogicalToDeviceY(yc), LogicalToDeviceXRel(radius), LogicalToDeviceYRel(radius), (wxCoord)alpha1, (wxCoord) alpha2,
-                LogicalToDeviceX(xc), LogicalToDeviceY(yc) );
+        wxString buffer;
+        buffer.Printf( "newpath\n"
+                       "%f %f %f %f %f %f ellipse\n"
+                       "%f %f lineto\n"
+                       "closepath\n"
+                       "fill\n",
+                XLOG2DEV(xc), YLOG2DEV(yc),
+                XLOG2DEVREL(i_radius), YLOG2DEVREL(i_radius),
+                alpha1, alpha2,
+                XLOG2DEV(xc), YLOG2DEV(yc) );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
-        CalcBoundingBox( xc-radius, yc-radius );
-        CalcBoundingBox( xc+radius, yc+radius );
+        CalcBoundingBox( xc-i_radius, yc-i_radius );
+        CalcBoundingBox( xc+i_radius, yc+i_radius );
     }
 
     if (m_pen.GetStyle() != wxTRANSPARENT)
     {
         SetPen( m_pen );
 
-        PsPrintf( wxT("newpath\n")
-                  wxT("%d %d %d %d %d %d ellipse\n")
-                  wxT("%d %d lineto\n")
-                  wxT("stroke\n")
-                  wxT("fill\n"),
-                LogicalToDeviceX(xc), LogicalToDeviceY(yc), LogicalToDeviceXRel(radius), LogicalToDeviceYRel(radius), (wxCoord)alpha1, (wxCoord) alpha2,
-                LogicalToDeviceX(xc), LogicalToDeviceY(yc) );
+        wxString buffer;
+        buffer.Printf( "newpath\n"
+                       "%f %f %f %f %f %f ellipse\n"
+                       "%f %f lineto\n"
+                       "closepath\n"
+                       "stroke\n",
+                XLOG2DEV(xc), YLOG2DEV(yc),
+                XLOG2DEVREL(i_radius), YLOG2DEVREL(i_radius),
+                alpha1, alpha2,
+                XLOG2DEV(xc), YLOG2DEV(yc) );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
-        CalcBoundingBox( xc-radius, yc-radius );
-        CalcBoundingBox( xc+radius, yc+radius );
+        CalcBoundingBox( xc-i_radius, yc-i_radius );
+        CalcBoundingBox( xc+i_radius, yc+i_radius );
     }
 }
 
@@ -477,11 +502,14 @@ void wxPostScriptDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,d
     {
         SetBrush( m_brush );
 
-        PsPrintf( wxT("newpath\n")
-                  wxT("%d %d %d %d %d %d true ellipticarc\n"),
-                  LogicalToDeviceX(x+w/2), LogicalToDeviceY(y+h/2),
-                  LogicalToDeviceXRel(w/2), LogicalToDeviceYRel(h/2),
-                  (wxCoord)sa, (wxCoord)ea );
+        wxString buffer;
+        buffer.Printf( "newpath\n"
+                       "%f %f %f %f %f %f true ellipticarc\n",
+                  XLOG2DEV(x+w/2), YLOG2DEV(y+h/2),
+                  XLOG2DEVREL(w/2), YLOG2DEVREL(h/2),
+                  sa, ea );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
         CalcBoundingBox( x ,y );
         CalcBoundingBox( x+w, y+h );
@@ -491,11 +519,14 @@ void wxPostScriptDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,d
     {
         SetPen( m_pen );
 
-        PsPrintf( wxT("newpath\n")
-                  wxT("%d %d %d %d %d %d false ellipticarc\n"),
-                LogicalToDeviceX(x+w/2), LogicalToDeviceY(y+h/2),
-                LogicalToDeviceXRel(w/2), LogicalToDeviceYRel(h/2),
-                (wxCoord)sa, (wxCoord)ea );
+        wxString buffer;
+        buffer.Printf( "newpath\n"
+                       "%f %f %f %f %f %f false ellipticarc\n",
+                  XLOG2DEV(x+w/2), YLOG2DEV(y+h/2),
+                  XLOG2DEVREL(w/2), YLOG2DEVREL(h/2),
+                  sa, ea );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
         CalcBoundingBox( x ,y );
         CalcBoundingBox( x+w, y+h );
@@ -510,12 +541,15 @@ void wxPostScriptDC::DoDrawPoint (wxCoord x, wxCoord y)
 
     SetPen (m_pen);
 
-    PsPrintf( wxT("newpath\n")
-              wxT("%d %d moveto\n")
-              wxT("%d %d lineto\n")
-              wxT("stroke\n"),
-            LogicalToDeviceX(x),   LogicalToDeviceY(y),
-            LogicalToDeviceX(x+1), LogicalToDeviceY(y) );
+    wxString buffer;
+    buffer.Printf( "newpath\n"
+                   "%f %f moveto\n"
+                   "%f %f lineto\n"
+                   "stroke\n",
+            XLOG2DEV(x),   YLOG2DEV(y),
+            XLOG2DEV(x+1), YLOG2DEV(y) );
+    buffer.Replace( ",", "." );
+    PsPrint( buffer );
 
     CalcBoundingBox( x, y );
 }
@@ -532,19 +566,24 @@ void wxPostScriptDC::DoDrawPolygon (int n, wxPoint points[], wxCoord xoffset, wx
 
         PsPrint( "newpath\n" );
 
-        wxCoord xx = LogicalToDeviceX(points[0].x + xoffset);
-        wxCoord yy = LogicalToDeviceY(points[0].y + yoffset);
+        double xx = XLOG2DEV(points[0].x + xoffset);
+        double yy = YLOG2DEV(points[0].y + yoffset);
 
-        PsPrintf( wxT("%d %d moveto\n"), xx, yy );
+        wxString buffer;
+        buffer.Printf( "%f %f moveto\n", xx, yy );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
         CalcBoundingBox( points[0].x + xoffset, points[0].y + yoffset );
 
         for (int i = 1; i < n; i++)
         {
-            xx = LogicalToDeviceX(points[i].x + xoffset);
-            yy = LogicalToDeviceY(points[i].y + yoffset);
+            xx = XLOG2DEV(points[i].x + xoffset);
+            yy = YLOG2DEV(points[i].y + yoffset);
 
-            PsPrintf( wxT("%d %d lineto\n"), xx, yy );
+            buffer.Printf( "%f %f lineto\n", xx, yy );
+            buffer.Replace( ",", "." );
+            PsPrint( buffer );
 
             CalcBoundingBox( points[i].x + xoffset, points[i].y + yoffset);
         }
@@ -558,19 +597,24 @@ void wxPostScriptDC::DoDrawPolygon (int n, wxPoint points[], wxCoord xoffset, wx
 
         PsPrint( "newpath\n" );
 
-        wxCoord xx = LogicalToDeviceX(points[0].x + xoffset);
-        wxCoord yy = LogicalToDeviceY(points[0].y + yoffset);
+        double xx = XLOG2DEV(points[0].x + xoffset);
+        double yy = YLOG2DEV(points[0].y + yoffset);
 
-        PsPrintf( wxT("%d %d moveto\n"), xx, yy );
+        wxString buffer;
+        buffer.Printf( "%f %f moveto\n", xx, yy );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
         CalcBoundingBox( points[0].x + xoffset, points[0].y + yoffset );
 
         for (int i = 1; i < n; i++)
         {
-            xx = LogicalToDeviceX(points[i].x + xoffset);
-            yy = LogicalToDeviceY(points[i].y + yoffset);
+            xx = XLOG2DEV(points[i].x + xoffset);
+            yy = YLOG2DEV(points[i].y + yoffset);
 
-            PsPrintf( wxT("%d %d lineto\n"), xx, yy );
+            buffer.Printf( "%f %f lineto\n", xx, yy );
+            buffer.Replace( ",", "." );
+            PsPrint( buffer );
 
             CalcBoundingBox( points[i].x + xoffset, points[i].y + yoffset);
         }
@@ -595,19 +639,24 @@ void wxPostScriptDC::DoDrawPolyPolygon (int n, int count[], wxPoint points[], wx
         int ofs = 0;
         for (int i = 0; i < n; ofs += count[i++])
         {
-            wxCoord xx = LogicalToDeviceX(points[ofs].x + xoffset);
-            wxCoord yy = LogicalToDeviceY(points[ofs].y + yoffset);
+            double xx = XLOG2DEV(points[ofs].x + xoffset);
+            double yy = YLOG2DEV(points[ofs].y + yoffset);
 
-            PsPrintf( wxT("%d %d moveto\n"), xx, yy );
+            wxString buffer;
+            buffer.Printf( "%f %f moveto\n", xx, yy );
+            buffer.Replace( ",", "." );
+            PsPrint( buffer );
 
             CalcBoundingBox( points[ofs].x + xoffset, points[ofs].y + yoffset );
 
             for (int j = 1; j < count[i]; j++)
             {
-                xx = LogicalToDeviceX(points[ofs+j].x + xoffset);
-                yy = LogicalToDeviceY(points[ofs+j].y + yoffset);
+                xx = XLOG2DEV(points[ofs+j].x + xoffset);
+                yy = YLOG2DEV(points[ofs+j].y + yoffset);
 
-                PsPrintf( wxT("%d %d lineto\n"), xx, yy );
+                buffer.Printf( "%f %f lineto\n", xx, yy );
+                buffer.Replace( ",", "." );
+                PsPrint( buffer );
 
                 CalcBoundingBox( points[ofs+j].x + xoffset, points[ofs+j].y + yoffset);
             }
@@ -624,19 +673,24 @@ void wxPostScriptDC::DoDrawPolyPolygon (int n, int count[], wxPoint points[], wx
         int ofs = 0;
         for (int i = 0; i < n; ofs += count[i++])
         {
-            wxCoord xx = LogicalToDeviceX(points[ofs].x + xoffset);
-            wxCoord yy = LogicalToDeviceY(points[ofs].y + yoffset);
+            double xx = XLOG2DEV(points[ofs].x + xoffset);
+            double yy = YLOG2DEV(points[ofs].y + yoffset);
 
-            PsPrintf( wxT("%d %d moveto\n"), xx, yy );
+            wxString buffer;
+            buffer.Printf( "%f %f moveto\n", xx, yy );
+            buffer.Replace( ",", "." );
+            PsPrint( buffer );
 
             CalcBoundingBox( points[ofs].x + xoffset, points[ofs].y + yoffset );
 
             for (int j = 1; j < count[i]; j++)
             {
-                xx = LogicalToDeviceX(points[ofs+j].x + xoffset);
-                yy = LogicalToDeviceY(points[ofs+j].y + yoffset);
+                xx = XLOG2DEV(points[ofs+j].x + xoffset);
+                yy = YLOG2DEV(points[ofs+j].y + yoffset);
 
-                PsPrintf( wxT("%d %d lineto\n"), xx, yy );
+                buffer.Printf( "%f %f lineto\n", xx, yy );
+                buffer.Replace( ",", "." );
+                PsPrint( buffer );
 
                 CalcBoundingBox( points[ofs+j].x + xoffset, points[ofs+j].y + yoffset);
             }
@@ -658,20 +712,23 @@ void wxPostScriptDC::DoDrawLines (int n, wxPoint points[], wxCoord xoffset, wxCo
 
     int i;
     for ( i =0; i<n ; i++ )
-    {
-        CalcBoundingBox( LogicalToDeviceX(points[i].x+xoffset), LogicalToDeviceY(points[i].y+yoffset));
-    }
-
-    PsPrintf( wxT("newpath\n")
-              wxT("%d %d moveto\n"),
-              LogicalToDeviceX(points[0].x+xoffset),
-              LogicalToDeviceY(points[0].y+yoffset) );
+        CalcBoundingBox( points[i].x+xoffset, points[i].y+yoffset );
+
+    wxString buffer;
+    buffer.Printf( "newpath\n"
+                   "%f %f moveto\n",
+              XLOG2DEV(points[0].x+xoffset),
+              YLOG2DEV(points[0].y+yoffset) );
+    buffer.Replace( ",", "." );
+    PsPrint( buffer );
 
     for (i = 1; i < n; i++)
     {
-        PsPrintf( wxT("%d %d lineto\n"),
-                  LogicalToDeviceX(points[i].x+xoffset),
-                  LogicalToDeviceY(points[i].y+yoffset) );
+        buffer.Printf( "%f %f lineto\n",
+                  XLOG2DEV(points[i].x+xoffset),
+                  YLOG2DEV(points[i].y+yoffset) );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
     }
 
     PsPrint( "stroke\n" );
@@ -681,21 +738,27 @@ void wxPostScriptDC::DoDrawRectangle (wxCoord x, wxCoord y, wxCoord width, wxCoo
 {
     wxCHECK_RET( m_ok, wxT("invalid postscript dc") );
 
+    width--;
+    height--;
+
     if (m_brush.GetStyle () != wxTRANSPARENT)
     {
         SetBrush( m_brush );
 
-        PsPrintf( wxT("newpath\n")
-                  wxT("%d %d moveto\n")
-                  wxT("%d %d lineto\n")
-                  wxT("%d %d lineto\n")
-                  wxT("%d %d lineto\n")
-                  wxT("closepath\n")
-                  wxT("fill\n"),
-                LogicalToDeviceX(x),         LogicalToDeviceY(y),
-                LogicalToDeviceX(x + width), LogicalToDeviceY(y),
-                LogicalToDeviceX(x + width), LogicalToDeviceY(y + height),
-                LogicalToDeviceX(x),         LogicalToDeviceY(y + height) );
+        wxString buffer;
+        buffer.Printf( "newpath\n"
+                       "%f %f moveto\n"
+                       "%f %f lineto\n"
+                       "%f %f lineto\n"
+                       "%f %f lineto\n"
+                       "closepath\n"
+                       "fill\n",
+                XLOG2DEV(x),         YLOG2DEV(y),
+                XLOG2DEV(x + width), YLOG2DEV(y),
+                XLOG2DEV(x + width), YLOG2DEV(y + height),
+                XLOG2DEV(x),         YLOG2DEV(y + height) );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
         CalcBoundingBox( x, y );
         CalcBoundingBox( x + width, y + height );
@@ -705,17 +768,20 @@ void wxPostScriptDC::DoDrawRectangle (wxCoord x, wxCoord y, wxCoord width, wxCoo
     {
         SetPen (m_pen);
 
-        PsPrintf( wxT("newpath\n")
-                  wxT("%d %d moveto\n")
-                  wxT("%d %d lineto\n")
-                  wxT("%d %d lineto\n")
-                  wxT("%d %d lineto\n")
-                  wxT("closepath\n")
-                  wxT("stroke\n"),
-                LogicalToDeviceX(x),         LogicalToDeviceY(y),
-                LogicalToDeviceX(x + width), LogicalToDeviceY(y),
-                LogicalToDeviceX(x + width), LogicalToDeviceY(y + height),
-                LogicalToDeviceX(x),         LogicalToDeviceY(y + height) );
+        wxString buffer;
+        buffer.Printf( "newpath\n"
+                       "%f %f moveto\n"
+                       "%f %f lineto\n"
+                       "%f %f lineto\n"
+                       "%f %f lineto\n"
+                       "closepath\n"
+                       "stroke\n",
+                XLOG2DEV(x),         YLOG2DEV(y),
+                XLOG2DEV(x + width), YLOG2DEV(y),
+                XLOG2DEV(x + width), YLOG2DEV(y + height),
+                XLOG2DEV(x),         YLOG2DEV(y + height) );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
         CalcBoundingBox( x, y );
         CalcBoundingBox( x + width, y + height );
@@ -726,6 +792,9 @@ void wxPostScriptDC::DoDrawRoundedRectangle (wxCoord x, wxCoord y, wxCoord width
 {
     wxCHECK_RET( m_ok, wxT("invalid postscript dc") );
 
+    width--;
+    height--;
+
     if (radius < 0.0)
     {
         // Now, a negative radius is interpreted to mean
@@ -741,25 +810,28 @@ void wxPostScriptDC::DoDrawRoundedRectangle (wxCoord x, wxCoord y, wxCoord width
         SetBrush( m_brush );
 
         /* Draw rectangle anticlockwise */
-        PsPrintf( wxT("newpath\n")
-                  wxT("%d %d %d 90 180 arc\n")
-                  wxT("%d %d lineto\n")
-                  wxT("%d %d %d 180 270 arc\n")
-                  wxT("%d %d lineto\n")
-                  wxT("%d %d %d 270 0 arc\n")
-                  wxT("%d %d lineto\n")
-                  wxT("%d %d %d 0 90 arc\n")
-                  wxT("%d %d lineto\n")
-                  wxT("closepath\n")
-                  wxT("fill\n"),
-                LogicalToDeviceX(x + rad), LogicalToDeviceY(y + rad), LogicalToDeviceXRel(rad),
-                LogicalToDeviceX(x), LogicalToDeviceY(y + height - rad),
-                LogicalToDeviceX(x + rad), LogicalToDeviceY(y + height - rad), LogicalToDeviceXRel(rad),
-                LogicalToDeviceX(x + width - rad), LogicalToDeviceY(y + height),
-                LogicalToDeviceX(x + width - rad), LogicalToDeviceY(y + height - rad), LogicalToDeviceXRel(rad),
-                LogicalToDeviceX(x + width), LogicalToDeviceY(y + rad),
-                LogicalToDeviceX(x + width - rad), LogicalToDeviceY(y + rad), LogicalToDeviceXRel(rad),
-                LogicalToDeviceX(x + rad), LogicalToDeviceY(y) );
+        wxString buffer;
+        buffer.Printf( "newpath\n"
+                       "%f %f %f 90 180 arc\n"
+                       "%f %f lineto\n"
+                       "%f %f %f 180 270 arc\n"
+                       "%f %f lineto\n"
+                       "%f %f %f 270 0 arc\n"
+                       "%f %f lineto\n"
+                       "%f %f %f 0 90 arc\n"
+                       "%f %f lineto\n"
+                       "closepath\n"
+                       "fill\n",
+                XLOG2DEV(x + rad), YLOG2DEV(y + rad), XLOG2DEVREL(rad),
+                XLOG2DEV(x), YLOG2DEV(y + height - rad),
+                XLOG2DEV(x + rad), YLOG2DEV(y + height - rad), XLOG2DEVREL(rad),
+                XLOG2DEV(x + width - rad), YLOG2DEV(y + height),
+                XLOG2DEV(x + width - rad), YLOG2DEV(y + height - rad), XLOG2DEVREL(rad),
+                XLOG2DEV(x + width), YLOG2DEV(y + rad),
+                XLOG2DEV(x + width - rad), YLOG2DEV(y + rad), XLOG2DEVREL(rad),
+                XLOG2DEV(x + rad), YLOG2DEV(y) );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
         CalcBoundingBox( x, y );
         CalcBoundingBox( x + width, y + height );
@@ -770,25 +842,28 @@ void wxPostScriptDC::DoDrawRoundedRectangle (wxCoord x, wxCoord y, wxCoord width
         SetPen (m_pen);
 
         /* Draw rectangle anticlockwise */
-        PsPrintf( wxT("newpath\n")
-                  wxT("%d %d %d 90 180 arc\n")
-                  wxT("%d %d lineto\n")
-                  wxT("%d %d %d 180 270 arc\n")
-                  wxT("%d %d lineto\n")
-                  wxT("%d %d %d 270 0 arc\n")
-                  wxT("%d %d lineto\n")
-                  wxT("%d %d %d 0 90 arc\n")
-                  wxT("%d %d lineto\n")
-                  wxT("closepath\n")
-                  wxT("stroke\n"),
-                LogicalToDeviceX(x + rad), LogicalToDeviceY(y + rad), LogicalToDeviceXRel(rad),
-                LogicalToDeviceX(x), LogicalToDeviceY(y + height - rad),
-                LogicalToDeviceX(x + rad), LogicalToDeviceY(y + height - rad), LogicalToDeviceXRel(rad),
-                LogicalToDeviceX(x + width - rad), LogicalToDeviceY(y + height),
-                LogicalToDeviceX(x + width - rad), LogicalToDeviceY(y + height - rad), LogicalToDeviceXRel(rad),
-                LogicalToDeviceX(x + width), LogicalToDeviceY(y + rad),
-                LogicalToDeviceX(x + width - rad), LogicalToDeviceY(y + rad), LogicalToDeviceXRel(rad),
-                LogicalToDeviceX(x + rad), LogicalToDeviceY(y) );
+        wxString buffer;
+        buffer.Printf( "newpath\n"
+                       "%f %f %f 90 180 arc\n"
+                       "%f %f lineto\n"
+                       "%f %f %f 180 270 arc\n"
+                       "%f %f lineto\n"
+                       "%f %f %f 270 0 arc\n"
+                       "%f %f lineto\n"
+                       "%f %f %f 0 90 arc\n"
+                       "%f %f lineto\n"
+                       "closepath\n"
+                       "stroke\n",
+                XLOG2DEV(x + rad), YLOG2DEV(y + rad), XLOG2DEVREL(rad),
+                XLOG2DEV(x), YLOG2DEV(y + height - rad),
+                XLOG2DEV(x + rad), YLOG2DEV(y + height - rad), XLOG2DEVREL(rad),
+                XLOG2DEV(x + width - rad), YLOG2DEV(y + height),
+                XLOG2DEV(x + width - rad), YLOG2DEV(y + height - rad), XLOG2DEVREL(rad),
+                XLOG2DEV(x + width), YLOG2DEV(y + rad),
+                XLOG2DEV(x + width - rad), YLOG2DEV(y + rad), XLOG2DEVREL(rad),
+                XLOG2DEV(x + rad), YLOG2DEV(y) );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
         CalcBoundingBox( x, y );
         CalcBoundingBox( x + width, y + height );
@@ -799,15 +874,21 @@ void wxPostScriptDC::DoDrawEllipse (wxCoord x, wxCoord y, wxCoord width, wxCoord
 {
     wxCHECK_RET( m_ok, wxT("invalid postscript dc") );
 
+    width--;
+    height--;
+
     if (m_brush.GetStyle () != wxTRANSPARENT)
     {
         SetBrush (m_brush);
 
-        PsPrintf( wxT("newpath\n")
-                  wxT("%d %d %d %d 0 360 ellipse\n")
-                  wxT("fill\n"),
-                LogicalToDeviceX(x + width / 2), LogicalToDeviceY(y + height / 2),
-                LogicalToDeviceXRel(width / 2), LogicalToDeviceYRel(height / 2) );
+        wxString buffer;
+        buffer.Printf( "newpath\n"
+                       "%f %f %f %f 0 360 ellipse\n"
+                       "fill\n",
+                XLOG2DEV(x + width / 2), YLOG2DEV(y + height / 2),
+                XLOG2DEVREL(width / 2), YLOG2DEVREL(height / 2) );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
         CalcBoundingBox( x - width, y - height );
         CalcBoundingBox( x + width, y + height );
@@ -817,11 +898,14 @@ void wxPostScriptDC::DoDrawEllipse (wxCoord x, wxCoord y, wxCoord width, wxCoord
     {
         SetPen (m_pen);
 
-        PsPrintf( wxT("newpath\n")
-                  wxT("%d %d %d %d 0 360 ellipse\n")
-                  wxT("stroke\n"),
-                LogicalToDeviceX(x + width / 2), LogicalToDeviceY(y + height / 2),
-                LogicalToDeviceXRel(width / 2), LogicalToDeviceYRel(height / 2) );
+        wxString buffer;
+        buffer.Printf( "newpath\n"
+                       "%f %f %f %f 0 360 ellipse\n"
+                       "stroke\n",
+                XLOG2DEV(x + width / 2), YLOG2DEV(y + height / 2),
+                XLOG2DEVREL(width / 2), YLOG2DEVREL(height / 2) );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
         CalcBoundingBox( x - width, y - height );
         CalcBoundingBox( x + width, y + height );
@@ -849,36 +933,39 @@ void wxPostScriptDC::DoDrawBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y,
     wxCoord w = image.GetWidth();
     wxCoord h = image.GetHeight();
 
-    wxCoord ww = LogicalToDeviceXRel(image.GetWidth());
-    wxCoord hh = LogicalToDeviceYRel(image.GetHeight());
-
-    wxCoord xx = LogicalToDeviceX(x);
-    wxCoord yy = LogicalToDeviceY(y + bitmap.GetHeight());
-
-    PsPrintf( wxT("/origstate save def\n")
-              wxT("20 dict begin\n")
-              wxT("/pix %d string def\n")
-              wxT("/grays %d string def\n")
-              wxT("/npixels 0 def\n")
-              wxT("/rgbindx 0 def\n")
-              wxT("%d %d translate\n")
-              wxT("%d %d scale\n")
-              wxT("%d %d 8\n")
-              wxT("[%d 0 0 %d 0 %d]\n")
-              wxT("{currentfile pix readhexstring pop}\n")
-              wxT("false 3 colorimage\n"),
+    double ww = XLOG2DEVREL(image.GetWidth());
+    double hh = YLOG2DEVREL(image.GetHeight());
+
+    double xx = XLOG2DEV(x);
+    double yy = YLOG2DEV(y + bitmap.GetHeight());
+
+    wxString buffer;
+    buffer.Printf( "/origstate save def\n"
+                   "20 dict begin\n"
+                   "/pix %d string def\n"
+                   "/grays %d string def\n"
+                   "/npixels 0 def\n"
+                   "/rgbindx 0 def\n"
+                   "%f %f translate\n"
+                   "%f %f scale\n"
+                   "%d %d 8\n"
+                   "[%d 0 0 %d 0 %d]\n"
+                   "{currentfile pix readhexstring pop}\n"
+                   "false 3 colorimage\n",
             w, w, xx, yy, ww, hh, w, h, w, -h, h );
+    buffer.Replace( ",", "." );
+    PsPrint( buffer );
 
     unsigned char* data = image.GetData();
 
     // size of the buffer = width*rgb(3)*hexa(2)+'\n'
-    wxCharBuffer buffer(w*6 + 1);
+    wxCharBuffer charbuffer(w*6 + 1);
     int firstDigit, secondDigit;
 
     //rows
     for (int j = 0; j < h; j++)
     {
-        char* bufferindex = buffer.data();
+        char* bufferindex = charbuffer.data();
 
         //cols
         for (int i = 0; i < w*3; i++)
@@ -892,7 +979,11 @@ void wxPostScriptDC::DoDrawBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y,
         }
         *(bufferindex++) = '\n';
         *bufferindex = 0;
-        PsPrint( buffer );
+
+        if (m_pstream)
+            fwrite( charbuffer, 1, strlen( charbuffer ), m_pstream );
+        else
+            PsPrint( charbuffer );
     }
 
     PsPrint( "end\n" );
@@ -985,13 +1076,11 @@ void wxPostScriptDC::SetFont( const wxFont& font )
     PsPrint( name );
     PsPrint( " findfont\n" );
 
-    char buffer[100];
-    sprintf( buffer, "%f scalefont setfont\n", LogicalToDeviceYRel(m_font.GetPointSize() * 1000) / 1000.0F);
-    // this is a hack - we must scale font size (in pts) according to m_scaleY but
-    // LogicalToDeviceYRel works with wxCoord type (int or longint). Se we first convert font size
-    // to 1/1000th of pt and then back.
-    for (int i = 0; i < 100; i++)
-        if (buffer[i] == ',') buffer[i] = '.';
+
+    double size = (double) m_font.GetPointSize();
+    wxString buffer;
+    buffer.Printf( "%f scalefont setfont\n", size * DEV2PS * m_scaleX );
+    buffer.Replace( ",", "." );
     PsPrint( buffer );
 }
 
@@ -1005,10 +1094,16 @@ void wxPostScriptDC::SetPen( const wxPen& pen )
 
     m_pen = pen;
 
-    char buffer[100];
-    sprintf( buffer, "%f setlinewidth\n", LogicalToDeviceXRel(1000 * m_pen.GetWidth()) / 1000.0f );
-    for (int i = 0; i < 100; i++)
-        if (buffer[i] == ',') buffer[i] = '.';
+    double width;
+
+    if (m_pen.GetWidth() <= 0)
+        width = 0.1;
+    else
+        width = (double) m_pen.GetWidth();
+
+    wxString buffer;
+    buffer.Printf( "%f setlinewidth\n", width * DEV2PS * m_scaleX );
+    buffer.Replace( ",", "." );
     PsPrint( buffer );
 
 /*
@@ -1043,7 +1138,7 @@ void wxPostScriptDC::SetPen( const wxPen& pen )
             PsPrint ("[");
             for (int i = 0; i < nDashes; ++i)
             {
-                sprintf( buffer, "%d ", dashes [i] );
+                buffer.Printf( "%d ", dashes [i] );
                 PsPrint( buffer );
             }
             PsPrint ("] 0 setdash\n");
@@ -1086,12 +1181,9 @@ void wxPostScriptDC::SetPen( const wxPen& pen )
         double bluePS = (double)(blue) / 255.0;
         double greenPS = (double)(green) / 255.0;
 
-        sprintf( buffer,
-            "%.8f %.8f %.8f setrgbcolor\n",
-            redPS, greenPS, bluePS );
-        for (int i = 0; i < 100; i++)
-            if (buffer[i] == ',') buffer[i] = '.';
-
+        wxString buffer;
+        buffer.Printf( "%f %f %f setrgbcolor\n", redPS, greenPS, bluePS );
+        buffer.Replace( ",", "." );
         PsPrint( buffer );
 
         m_currentRed = red;
@@ -1133,13 +1225,9 @@ void wxPostScriptDC::SetBrush( const wxBrush& brush )
         double bluePS = (double)(blue) / 255.0;
         double greenPS = (double)(green) / 255.0;
 
-        char buffer[100];
-        sprintf( buffer,
-                "%.8f %.8f %.8f setrgbcolor\n",
-                redPS, greenPS, bluePS );
-        for (int i = 0; i < 100; i++)
-            if (buffer[i] == ',') buffer[i] = '.';
-
+        wxString buffer;
+        buffer.Printf( "%f %f %f setrgbcolor\n", redPS, greenPS, bluePS );
+        buffer.Replace( ",", "." );
         PsPrint( buffer );
 
         m_currentRed = red;
@@ -1152,6 +1240,10 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
 {
     wxCHECK_RET( m_ok, wxT("invalid postscript dc") );
 
+    const wxWX2MBbuf textbuf = text.mb_str();
+    if ( !textbuf )
+        return;
+
     if (m_textForegroundColour.Ok())
     {
         unsigned char red = m_textForegroundColour.Red();
@@ -1178,12 +1270,9 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
             double bluePS = (double)(blue) / 255.0;
             double greenPS = (double)(green) / 255.0;
 
-            char buffer[100];
-            sprintf( buffer,
-                "%.8f %.8f %.8f setrgbcolor\n",
-                redPS, greenPS, bluePS );
-            for (size_t i = 0; i < strlen(buffer); i++)
-                if (buffer[i] == ',') buffer[i] = '.';
+            wxString buffer;
+            buffer.Printf( "%f %f %f setrgbcolor\n", redPS, greenPS, bluePS );
+            buffer.Replace( ",", "." );
             PsPrint( buffer );
 
             m_currentRed = red;
@@ -1196,11 +1285,6 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
 
     GetTextExtent(text, &text_w, &text_h, &text_descent);
 
-    // VZ: this seems to be unnecessary, so taking it out for now, if it
-    //     doesn't create any problems, remove this comment entirely
-    //SetFont( m_font );
-
-
     int size = m_font.GetPointSize();
 
 //    wxCoord by = y + (wxCoord)floor( double(size) * 2.0 / 3.0 ); // approximate baseline
@@ -1208,10 +1292,12 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
 //        - note that there is still rounding error in text_descent!
     wxCoord by = y + size - text_descent; // baseline
 
-    PsPrintf( wxT("%d %d moveto\n"), LogicalToDeviceX(x), LogicalToDeviceY(by) );
+    wxString buffer;
+    buffer.Printf( "%f %f moveto\n", XLOG2DEV(x), YLOG2DEV(by) );
+    buffer.Replace( ",", "." );
+    PsPrint( buffer );
     PsPrint( "(" );
 
-    const wxWX2MBbuf textbuf = text.mb_str();
     size_t len = strlen(textbuf);
     size_t i;
     for (i = 0; i < len; i++)
@@ -1221,16 +1307,17 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
         {
             /* Cope with special characters */
             PsPrint( "\\" );
-            PsPrint(c);
+            PsPrint( (char) c );
         }
         else if ( c >= 128 )
         {
             /* Cope with character codes > 127 */
-            PsPrintf( wxT("\\%o"), c);
+            buffer.Printf( "\\%o", c );
+            PsPrint( buffer );
         }
         else
         {
-            PsPrint(c);
+            PsPrint( (char) c );
         }
     }
 
@@ -1239,20 +1326,17 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
     if (m_font.GetUnderlined())
     {
         wxCoord uy = (wxCoord)(y + size - m_underlinePosition);
-        char buffer[100];
 
-        sprintf( buffer,
-                "gsave\n"
-                "%d %d moveto\n"
-                "%f setlinewidth\n"
-                "%d %d lineto\n"
-                "stroke\n"
-                "grestore\n",
-                LogicalToDeviceX(x), LogicalToDeviceY(uy),
+        buffer.Printf( "gsave\n"
+                       "%f %f moveto\n"
+                       "%f setlinewidth\n"
+                       "%f %f lineto\n"
+                       "stroke\n"
+                       "grestore\n",
+                XLOG2DEV(x), YLOG2DEV(uy),
                 m_underlineThickness,
-                LogicalToDeviceX(x + text_w), LogicalToDeviceY(uy) );
-        for (i = 0; i < 100; i++)
-            if (buffer[i] == ',') buffer[i] = '.';
+                XLOG2DEV(x + text_w), YLOG2DEV(uy) );
+        buffer.Replace( ",", "." );
         PsPrint( buffer );
     }
 
@@ -1298,12 +1382,9 @@ void wxPostScriptDC::DoDrawRotatedText( const wxString& text, wxCoord x, wxCoord
             double bluePS = (double)(blue) / 255.0;
             double greenPS = (double)(green) / 255.0;
 
-            char buffer[100];
-            sprintf( buffer,
-                "%.8f %.8f %.8f setrgbcolor\n",
-                redPS, greenPS, bluePS );
-            for (int i = 0; i < 100; i++)
-                if (buffer[i] == ',') buffer[i] = '.';
+            wxString buffer;
+            buffer.Printf( "%f %f %f setrgbcolor\n", redPS, greenPS, bluePS );
+            buffer.Replace( ",", "." );
             PsPrint( buffer );
 
             m_currentRed = red;
@@ -1314,21 +1395,19 @@ void wxPostScriptDC::DoDrawRotatedText( const wxString& text, wxCoord x, wxCoord
 
     int size = m_font.GetPointSize();
 
-    PsPrintf( wxT("%d %d moveto\n"),
-            LogicalToDeviceX(x), LogicalToDeviceY(y));
+    wxString buffer;
+    buffer.Printf( "%f %f moveto\n", XLOG2DEV(x), YLOG2DEV(y));
+    buffer.Replace( ",", "." );
+    PsPrint( buffer );
 
-    char buffer[100];
-    sprintf(buffer, "%.8f rotate\n", angle);
-    size_t i;
-    for (i = 0; i < 100; i++)
-    {
-        if (buffer[i] == ',') buffer[i] = '.';
-    }
-    PsPrint( buffer);
+    buffer.Printf( "%f rotate\n", angle );
+    buffer.Replace( ",", "." );
+    PsPrint( buffer );
 
     PsPrint( "(" );
     const wxWX2MBbuf textbuf = text.mb_str();
     size_t len = strlen(textbuf);
+    size_t i;
     for (i = 0; i < len; i++)
     {
         int c = (unsigned char) textbuf[i];
@@ -1336,26 +1415,24 @@ void wxPostScriptDC::DoDrawRotatedText( const wxString& text, wxCoord x, wxCoord
         {
             /* Cope with special characters */
             PsPrint( "\\" );
-            PsPrint(c);
+            PsPrint( (char) c );
         }
         else if ( c >= 128 )
         {
             /* Cope with character codes > 127 */
-            PsPrintf( wxT("\\%o"), c);
+            buffer.Printf( "\\%o", c);
+            PsPrint( buffer );
         }
         else
         {
-            PsPrint(c);
+            PsPrint( (char) c );
         }
     }
 
     PsPrint( ") show\n" );
 
-    sprintf( buffer, "%.8f rotate\n", -angle );
-    for (i = 0; i < 100; i++)
-    {
-        if (buffer[i] == ',') buffer[i] = '.';
-    }
+    buffer.Printf( "%f rotate\n", -angle );
+    buffer.Replace( ",", "." );
     PsPrint( buffer );
 
     if (m_font.GetUnderlined())
@@ -1364,20 +1441,17 @@ void wxPostScriptDC::DoDrawRotatedText( const wxString& text, wxCoord x, wxCoord
         wxCoord w, h;
         GetTextExtent(text, &w, &h);
 
-        sprintf( buffer,
+        buffer.Printf(
                 "gsave\n"
-                "%d %d moveto\n"
+                "%f %f moveto\n"
                 "%f setlinewidth\n"
-                "%d %d lineto\n"
+                "%f %f lineto\n"
                 "stroke\n"
                 "grestore\n",
-                LogicalToDeviceX(x), LogicalToDeviceY(uy),
+                XLOG2DEV(x), YLOG2DEV(uy),
                 m_underlineThickness,
-                LogicalToDeviceX(x + w), LogicalToDeviceY(uy) );
-        for (i = 0; i < 100; i++)
-        {
-            if (buffer[i] == ',') buffer[i] = '.';
-        }
+                XLOG2DEV(x + w), YLOG2DEV(uy) );
+        buffer.Replace( ",", "." );
         PsPrint( buffer );
     }
 
@@ -1396,7 +1470,7 @@ void wxPostScriptDC::SetLogicalFunction (int WXUNUSED(function))
 }
 
 #if wxUSE_SPLINES
-void wxPostScriptDC::DoDrawSpline( wxList *points )
+void wxPostScriptDC::DoDrawSpline( const wxPointList *points )
 {
     wxCHECK_RET( m_ok, wxT("invalid postscript dc") );
 
@@ -1407,13 +1481,13 @@ void wxPostScriptDC::DoDrawSpline( wxList *points )
     double c, d, x1, y1, x2, y2, x3, y3;
     wxPoint *p, *q;
 
-    wxList::compatibility_iterator node = points->GetFirst();
-    p = (wxPoint *)node->GetData();
+    wxPointList::compatibility_iterator node = points->GetFirst();
+    p = node->GetData();
     x1 = p->x;
     y1 = p->y;
 
     node = node->GetNext();
-    p = (wxPoint *)node->GetData();
+    p = node->GetData();
     c = p->x;
     d = p->y;
     x3 =
@@ -1427,11 +1501,14 @@ void wxPostScriptDC::DoDrawSpline( wxList *points )
          #endif
          (double)(y1 + d) / 2;
 
-    PsPrintf( wxT("newpath\n")
-              wxT("%d %d moveto\n")
-              wxT("%d %d lineto\n"),
-            LogicalToDeviceX((wxCoord)x1), LogicalToDeviceY((wxCoord)y1),
-            LogicalToDeviceX((wxCoord)x3), LogicalToDeviceY((wxCoord)y3) );
+    wxString buffer;
+    buffer.Printf( "newpath\n"
+                   "%f %f moveto\n"
+                   "%f %f lineto\n",
+            XLOG2DEV(wxRound(x1)), YLOG2DEV(wxRound(y1)),
+            XLOG2DEV(wxRound(x3)), YLOG2DEV(wxRound(y3)) );
+    buffer.Replace( ",", "." );
+    PsPrint( buffer );
 
     CalcBoundingBox( (wxCoord)x1, (wxCoord)y1 );
     CalcBoundingBox( (wxCoord)x3, (wxCoord)y3 );
@@ -1439,7 +1516,7 @@ void wxPostScriptDC::DoDrawSpline( wxList *points )
     node = node->GetNext();
     while (node)
     {
-        q = (wxPoint *)node->GetData();
+        q = node->GetData();
 
         x1 = x3;
         y1 = y3;
@@ -1450,10 +1527,12 @@ void wxPostScriptDC::DoDrawSpline( wxList *points )
         x3 = (double)(x2 + c) / 2;
         y3 = (double)(y2 + d) / 2;
 
-        PsPrintf( wxT("%d %d %d %d %d %d DrawSplineSection\n"),
-            LogicalToDeviceX((wxCoord)x1), LogicalToDeviceY((wxCoord)y1),
-            LogicalToDeviceX((wxCoord)x2), LogicalToDeviceY((wxCoord)y2),
-            LogicalToDeviceX((wxCoord)x3), LogicalToDeviceY((wxCoord)y3) );
+        buffer.Printf( "%f %f %f %f %f %f DrawSplineSection\n",
+            XLOG2DEV(wxRound(x1)), YLOG2DEV(wxRound(y1)),
+            XLOG2DEV(wxRound(x2)), YLOG2DEV(wxRound(y2)),
+            XLOG2DEV(wxRound(x3)), YLOG2DEV(wxRound(y3)) );
+        buffer.Replace( ",", "." );
+        PsPrint( buffer );
 
         CalcBoundingBox( (wxCoord)x1, (wxCoord)y1 );
         CalcBoundingBox( (wxCoord)x3, (wxCoord)y3 );
@@ -1466,9 +1545,9 @@ void wxPostScriptDC::DoDrawSpline( wxList *points )
        next-to-last and last point respectively, in the point list
      */
 
-    PsPrintf( wxT("%d %d lineto\n")
-              wxT("stroke\n"),
-            LogicalToDeviceX((wxCoord)c), LogicalToDeviceY((wxCoord)d) );
+    buffer.Printf( "%f %f lineto\nstroke\n", XLOG2DEV(wxRound(c)), YLOG2DEV(wxRound(d)) );
+    buffer.Replace( ",", "." );
+    PsPrint( buffer );
 }
 #endif // wxUSE_SPLINES
 
@@ -1478,26 +1557,77 @@ wxCoord wxPostScriptDC::GetCharWidth() const
     return (wxCoord) (GetCharHeight() * 72.0 / 120.0);
 }
 
+void wxPostScriptDC::SetPrintData(const wxPrintData& data)
+{
+    m_printData = data;
+
+    wxPaperSize id = m_printData.GetPaperId();
+    wxPrintPaperType *paper = wxThePrintPaperDatabase->FindPaperType(id);
+    if (!paper) paper = wxThePrintPaperDatabase->FindPaperType(wxPAPER_A4);
+    int w = 595;
+    int h = 842;
+    if (paper)
+    {
+        w = paper->GetSizeDeviceUnits().x;
+        h = paper->GetSizeDeviceUnits().y;
+    }
+
+    if (m_printData.GetOrientation() == wxLANDSCAPE)
+        m_pageHeight = w * PS2DEV;
+    else
+        m_pageHeight = h * PS2DEV;
+}
 
+#if wxUSE_NEW_DC
+#else
 void wxPostScriptDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
 {
-    wxCHECK_RET( m_ok, wxT("invalid postscript dc") );
+    wxDCBase::SetAxisOrientation(xLeftRight,yBottomUp);
+}
 
-    m_signX = (xLeftRight ? 1 : -1);
-    m_signY = (yBottomUp  ? 1 : -1);
+void wxPostScriptDC::SetMapMode(int mode)
+{
+    wxDCBase::SetMapMode(mode);
+}
 
-    ComputeScaleAndOrigin();
+void wxPostScriptDC::SetUserScale(double x, double y)
+{
+    wxDCBase::SetUserScale(x,y);
 }
 
-void wxPostScriptDC::SetDeviceOrigin( wxCoord x, wxCoord y )
+void wxPostScriptDC::SetLogicalScale(double x, double y)
 {
-    wxCHECK_RET( m_ok, wxT("invalid postscript dc") );
+    wxDCBase::SetLogicalScale(x,y);
+}
 
-    int h = 0;
-    int w = 0;
-    GetSize( &w, &h );
+void wxPostScriptDC::SetLogicalOrigin(wxCoord x, wxCoord y)
+{
+    wxDCBase::SetLogicalOrigin(x,y);
+}
+
+void wxPostScriptDC::SetDeviceOrigin(wxCoord x, wxCoord y)
+{
+    wxDCBase::SetDeviceOrigin(x,y);
+}
+#endif
+
+void wxPostScriptDC::ComputeScaleAndOrigin()
+{
+    const wxRealPoint origScale(m_scaleX, m_scaleY);
+
+#if wxUSE_NEW_DC
+    wxImplDC::ComputeScaleAndOrigin();
+#else
+    wxDC::ComputeScaleAndOrigin();
+#endif
 
-    wxDC::SetDeviceOrigin( x, h-y );
+    // If scale has changed call SetPen to recalulate the line width
+    // and SetFont to recalculate font size
+    if ( wxRealPoint(m_scaleX, m_scaleY) != origScale && m_pen.IsOk() )
+    {
+        SetPen( m_pen );
+        SetFont( m_font  );
+    }
 }
 
 void wxPostScriptDC::DoGetSize(int* width, int* height) const
@@ -1523,8 +1653,11 @@ void wxPostScriptDC::DoGetSize(int* width, int* height) const
         h = tmp;
     }
 
-    if (width) *width = (int)(w * ms_PSScaleFactor);
-    if (height) *height = (int)(h * ms_PSScaleFactor);
+    if (width)
+        *width = wxRound( w * PS2DEV );
+
+    if (height)
+        *height = wxRound( h * PS2DEV );
 }
 
 void wxPostScriptDC::DoGetSizeMM(int *width, int *height) const
@@ -1557,8 +1690,7 @@ void wxPostScriptDC::DoGetSizeMM(int *width, int *height) const
 // Resolution in pixels per logical inch
 wxSize wxPostScriptDC::GetPPI(void) const
 {
-    return wxSize((int)(72 * ms_PSScaleFactor),
-                  (int)(72 * ms_PSScaleFactor));
+    return wxSize( DPI, DPI );
 }
 
 
@@ -1587,17 +1719,22 @@ bool wxPostScriptDC::StartDoc( const wxString& message )
     m_ok = true;
     m_title = message;
 
+    wxString buffer;
+
     PsPrint( "%!PS-Adobe-2.0\n" );
-    PsPrintf( wxT("%%%%Title: %s\n"), m_title.c_str() );
+
+    buffer.Printf( "%%%%Title: %s\n", m_title );
+    PsPrint( buffer );
     PsPrint( "%%Creator: wxWidgets PostScript renderer\n" );
-    PsPrintf( wxT("%%%%CreationDate: %s\n"), wxNow().c_str() );
+
+    buffer.Printf( "%%%%CreationDate: %s\n", wxNow() );
+    PsPrint( buffer );
+
     if (m_printData.GetOrientation() == wxLANDSCAPE)
         PsPrint( "%%Orientation: Landscape\n" );
     else
         PsPrint( "%%Orientation: Portrait\n" );
 
-    // PsPrintf( wxT("%%%%Pages: %d\n"), (wxPageNumber - 1) );
-
     const wxChar *paper;
     switch (m_printData.GetPaperId())
     {
@@ -1617,7 +1754,10 @@ bool wxPostScriptDC::StartDoc( const wxString& message )
        case wxPAPER_10X14: paper = wxT("10x14"); break;         // 10-by-14-inch sheet
        default: paper = wxT("A4");
     }
-    PsPrintf( wxT("%%%%DocumentPaperSizes: %s\n"), paper );
+
+    buffer.Printf( "%%%%DocumentPaperSizes: %s\n", paper );
+    PsPrint( buffer );
+
     PsPrint( "%%EndComments\n\n" );
 
     PsPrint( "%%BeginProlog\n" );
@@ -1639,7 +1779,6 @@ bool wxPostScriptDC::StartDoc( const wxString& message )
     // set origin according to paper size
     SetDeviceOrigin( 0,0 );
 
-    wxPageNumber = 1;
     m_pageNumber = 1;
     return true;
 }
@@ -1672,10 +1811,10 @@ void wxPostScriptDC::EndDoc ()
 
     // Compute the bounding box.  Note that it is in the default user
     // coordinate system, thus we have to convert the values.
-    wxCoord minX = (wxCoord) LogicalToDeviceX(m_minX);
-    wxCoord minY = (wxCoord) LogicalToDeviceY(m_minY);
-    wxCoord maxX = (wxCoord) LogicalToDeviceX(m_maxX);
-    wxCoord maxY = (wxCoord) LogicalToDeviceY(m_maxY);
+    wxCoord minX = (wxCoord) XLOG2DEV(m_minX);
+    wxCoord minY = (wxCoord) YLOG2DEV(m_minY);
+    wxCoord maxX = (wxCoord) XLOG2DEV(m_maxX);
+    wxCoord maxY = (wxCoord) YLOG2DEV(m_maxY);
 
     // LOG2DEV may have changed the minimum to maximum vice versa
     if ( minX > maxX ) { wxCoord tmp = minX; minX = maxX; maxX = tmp; }
@@ -1748,48 +1887,38 @@ void wxPostScriptDC::StartPage()
 {
     wxCHECK_RET( m_ok, wxT("invalid postscript dc") );
 
-    PsPrintf( wxT("%%%%Page: %d\n"), wxPageNumber++ );
+    wxString buffer;
+    buffer.Printf( wxT("%%%%Page: %d\n"), m_pageNumber++ );
+    PsPrint( buffer );
 
-    //  What is this one supposed to do? RR.
-//  *m_pstream << "matrix currentmatrix\n";
+#if 0
+    wxPostScriptPrintNativeData *data =
+        (wxPostScriptPrintNativeData *) m_printData.GetNativeData();
 
-    // Added by Chris Breeze
+    wxCoord translate_x = (wxCoord)data->GetPrinterTranslateX();
+    wxCoord translate_y = (wxCoord)data->GetPrinterTranslateY();
 
-    // Each page starts with an "initgraphics" which resets the
-    // transformation and so we need to reset the origin
-    // (and rotate the page for landscape printing)
+    buffer.Printf( "%d %d translate\n", translate_x, translate_y );
+    PsPrint( buffer );
 
-    // Output scaling
-    wxCoord translate_x, translate_y;
-    double scale_x, scale_y;
+    double scale_x = data->GetPrinterScaleX();
+    double scale_y = data->GetPrinterScaleY();
 
-    wxPostScriptPrintNativeData *data =
-        (wxPostScriptPrintNativeData *) m_printData.GetNativeData();
+    buffer.Printf( "%f %f scale\n", scale_x, scale_y );
+    buffer.Replace( ",", "." );
+    PsPrint( buffer );
 
-    translate_x = (wxCoord)data->GetPrinterTranslateX();
-    translate_y = (wxCoord)data->GetPrinterTranslateY();
+#endif
+
+    // Each page starts with an "initgraphics" which resets the
+    // transformation and so we need to rotate the page for
+    // landscape printing)
 
-    scale_x = data->GetPrinterScaleX();
-    scale_y = data->GetPrinterScaleY();
+    // I copied this one from a PostScript tutorial, but to no avail. RR.
+    // PsPrint( "90 rotate llx neg ury nef translate\n" );
 
     if (m_printData.GetOrientation() == wxLANDSCAPE)
-    {
-        int h;
-        GetSize( (int*) NULL, &h );
-        translate_y -= h;
         PsPrint( "90 rotate\n" );
-        // I copied this one from a PostScript tutorial, but to no avail. RR.
-        // PsPrint( "90 rotate llx neg ury nef translate\n" );
-    }
-
-    char buffer[100];
-    sprintf( buffer, "%.8f %.8f scale\n", scale_x / ms_PSScaleFactor,
-            scale_y / ms_PSScaleFactor);
-    for (int i = 0; i < 100; i++)
-        if (buffer[i] == ',') buffer[i] = '.';
-    PsPrint( buffer );
-
-    PsPrintf( wxT("%d %d translate\n"), translate_x, translate_y );
 }
 
 void wxPostScriptDC::EndPage ()
@@ -1830,14 +1959,41 @@ wxCoord wxPostScriptDC::GetCharHeight() const
         return 12;
 }
 
+void wxPostScriptDC::PsPrint( const wxString& str )
+{
+    const wxCharBuffer psdata(str.utf8_str());
+
+    wxPostScriptPrintNativeData *data =
+        (wxPostScriptPrintNativeData *) m_printData.GetNativeData();
+
+    switch (m_printData.GetPrintMode())
+    {
+#if wxUSE_STREAMS
+        // append to output stream
+        case wxPRINT_MODE_STREAM:
+            {
+                wxOutputStream* outputstream = data->GetOutputStream();
+                wxCHECK_RET( outputstream, wxT("invalid outputstream") );
+                outputstream->Write( psdata, strlen( psdata ) );
+            }
+            break;
+#endif // wxUSE_STREAMS
+
+        // save data into file
+        default:
+            wxCHECK_RET( m_pstream, wxT("invalid postscript dc") );
+            fwrite( psdata, 1, strlen( psdata ), m_pstream );
+    }
+}
+
 void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                                      wxCoord *x, wxCoord *y,
                                      wxCoord *descent, wxCoord *externalLeading,
-                                     wxFont *theFont ) const
+                                     const wxFont *theFont ) const
 {
-    wxFont *fontToUse = theFont;
+    const wxFont *fontToUse = theFont;
 
-    if (!fontToUse) fontToUse = (wxFont*) &m_font;
+    if (!fontToUse) fontToUse = &m_font;
 
     wxCHECK_RET( fontToUse, wxT("GetTextExtent: no font defined") );
 
@@ -1854,6 +2010,10 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
 
     const wxWX2MBbuf strbuf = string.mb_str();
 
+    // conversion failed (non e.g. ISO characters)
+    if ( !strbuf )
+        return;
+
 #if !wxUSE_AFM_FOR_POSTSCRIPT
     /* Provide a VERY rough estimate (avoid using it).
      * Produces accurate results for mono-spaced font
@@ -1889,7 +2049,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
     /        in 'points' (1/72 of an inch). this should later on be
     /        changed to depend on the mapping mode.
     /  CAVE: the path to the AFM files must be set before calling this
-    /        function. this is usually done by a call like the following:
+    /        fun3B3Bction. this is usually done by a call like the following:
     /        wxSetAFMPath("d:\\wxw161\\afm\\");
     /
     /  example:
@@ -2134,9 +2294,9 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
         // VS: dirty, but is there any better solution?
         double *pt;
         pt = (double*) &m_underlinePosition;
-        *pt = LogicalToDeviceYRel((wxCoord)(UnderlinePosition * fontToUse->GetPointSize())) / 1000.0f;
+        *pt = YLOG2DEVREL((wxCoord)(UnderlinePosition * fontToUse->GetPointSize())) / 1000.0f;
         pt = (double*) &m_underlineThickness;
-        *pt = LogicalToDeviceYRel((wxCoord)(UnderlineThickness * fontToUse->GetPointSize())) / 1000.0f;
+        *pt = YLOG2DEVREL((wxCoord)(UnderlineThickness * fontToUse->GetPointSize())) / 1000.0f;
 
     }
 
@@ -2198,64 +2358,6 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
     // Use AFM
 }
 
-// print postscript datas via required method (file, stream)
-void wxPostScriptDC::PsPrintf( const wxChar* fmt, ... )
-{
-    va_list argptr;
-    va_start(argptr, fmt);
-
-    PsPrint( wxString::FormatV( fmt, argptr ).c_str() );
-}
-
-void wxPostScriptDC::PsPrint( const char* psdata )
-{
-    wxPostScriptPrintNativeData *data =
-        (wxPostScriptPrintNativeData *) m_printData.GetNativeData();
-
-    switch (m_printData.GetPrintMode())
-    {
-#if wxUSE_STREAMS
-        // append to output stream
-        case wxPRINT_MODE_STREAM:
-            {
-                wxOutputStream* outputstream = data->GetOutputStream();
-                wxCHECK_RET( outputstream, wxT("invalid outputstream") );
-                outputstream->Write( psdata, strlen( psdata ) );
-            }
-            break;
-#endif // wxUSE_STREAMS
-
-        // save data into file
-        default:
-            wxCHECK_RET( m_pstream, wxT("invalid postscript dc") );
-            fwrite( psdata, 1, strlen( psdata ), m_pstream );
-    }
-}
-
-void wxPostScriptDC::PsPrint( int ch )
-{
-    wxPostScriptPrintNativeData *data =
-        (wxPostScriptPrintNativeData *) m_printData.GetNativeData();
-
-    switch (m_printData.GetPrintMode())
-    {
-#if wxUSE_STREAMS
-        // append to output stream
-        case wxPRINT_MODE_STREAM:
-            {
-                wxOutputStream* outputstream = data->GetOutputStream();
-                wxCHECK_RET( outputstream, wxT("invalid outputstream") );
-                outputstream->PutC( (char)ch );
-            }
-            break;
-#endif // wxUSE_STREAMS
-
-        // save data into file
-        default:
-            wxCHECK_RET( m_pstream, wxT("invalid postscript dc") );
-            fputc( ch, m_pstream );
-    }
-}
 
 #endif // wxUSE_PRINTING_ARCHITECTURE && wxUSE_POSTSCRIPT