]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/dcpsg.cpp
(char*)(const char*)xxx.mb_str() is not a good
[wxWidgets.git] / src / generic / dcpsg.cpp
index 701c26e46f863c380c168e4a1bdebfd23621433f..47421d57b1ac6d94c0d64928f891e64aabada395 100644 (file)
@@ -10,8 +10,7 @@
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
-#pragma implementation
-#pragma interface
+#pragma implementation "dcpsg.h"
 #endif
 
 #include "wx/wxprec.h"
@@ -27,6 +26,8 @@
 
 #if wxUSE_POSTSCRIPT
 
+#include "wx/setup.h"
+
 #include "wx/window.h"
 #include "wx/dcmemory.h"
 #include "wx/utils.h"
@@ -37,7 +38,7 @@
 #include "wx/image.h"
 #include "wx/log.h"
 #include "wx/generic/dcpsg.h"
-#include "wx/generic/prntdlgg.h"
+#include "wx/printdlg.h"
 #include "wx/button.h"
 #include "wx/stattext.h"
 #include "wx/radiobox.h"
 // start and end of document/page
 //-----------------------------------------------------------------------------
 
+static const char *wxPostScriptHeaderConicTo = "\
+/conicto {\n\
+    /to_y exch def\n\
+    /to_x exch def\n\
+    /conic_cntrl_y exch def\n\
+    /conic_cntrl_x exch def\n\
+    currentpoint\n\
+    /p0_y exch def\n\
+    /p0_x exch def\n\
+    /p1_x p0_x conic_cntrl_x p0_x sub 2 3 div mul add def\n\
+    /p1_y p0_y conic_cntrl_y p0_y sub 2 3 div mul add def\n\
+    /p2_x p1_x to_x p0_x sub 1 3 div mul add def\n\
+    /p2_y p1_y to_y p0_y sub 1 3 div mul add def\n\
+    p1_x p1_y p2_x p2_y to_x to_y curveto\n\
+}  bind def\n\
+/start_ol { gsave 1.0 72 div dup scale } bind def\n\
+/end_ol { closepath fill grestore } bind def\n\
+";
+      
 static const char *wxPostScriptHeaderEllipse = "\
 /ellipsedict 8 dict def\n\
 ellipsedict /mtrx matrix put\n\
@@ -186,6 +206,7 @@ static const char *wxPostScriptHeaderColourImage = "\
   } ifelse          %% end of 'false' case\n\
 ";
 
+#ifndef __WXGTK20__
 static char wxPostScriptHeaderReencodeISO1[] =
     "\n/reencodeISO {\n"
 "dup dup findfont dup length dict begin\n"
@@ -226,6 +247,7 @@ static char wxPostScriptHeaderReencodeISO2[] =
 "/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis\n"
 "/yacute/thorn/ydieresis\n"
         "] def\n\n";
+#endif
 
 //-------------------------------------------------------------------------------
 // wxPostScriptDC
@@ -265,7 +287,7 @@ wxPostScriptDC::wxPostScriptDC ()
 
     // Compatibility only
     // HH: Doesn't seem to work for wxMSW...
-    #ifndef __WXMSW__
+    #if !defined(__WXMSW__)
     m_printData = * wxThePrintSetupData;
     #endif
 }
@@ -416,10 +438,10 @@ void wxPostScriptDC::DoSetClippingRegion (wxCoord x, wxCoord y, wxCoord w, wxCoo
             "%d %d lineto\n"
             "%d %d 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) );
+            LogicalToDeviceX(x),   LogicalToDeviceY(y),
+            LogicalToDeviceX(x+w), LogicalToDeviceY(y),
+            LogicalToDeviceX(x+w), LogicalToDeviceY(y+h),
+            LogicalToDeviceX(x),   LogicalToDeviceY(y+h) );
 }
 
 
@@ -441,9 +463,10 @@ void wxPostScriptDC::Clear()
     wxFAIL_MSG( wxT("wxPostScriptDC::Clear not implemented.") );
 }
 
-void wxPostScriptDC::DoFloodFill (wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), const wxColour &WXUNUSED(col), int WXUNUSED(style))
+bool wxPostScriptDC::DoFloodFill (wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), const wxColour &WXUNUSED(col), int WXUNUSED(style))
 {
     wxFAIL_MSG( wxT("wxPostScriptDC::FloodFill not implemented.") );
+    return FALSE;
 }
 
 bool wxPostScriptDC::DoGetPixel (wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxColour * WXUNUSED(col)) const
@@ -470,8 +493,8 @@ void wxPostScriptDC::DoDrawLine (wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
             "%d %d moveto\n"
             "%d %d lineto\n"
             "stroke\n",
-            XLOG2DEV(x1), YLOG2DEV(y1),
-            XLOG2DEV(x2), YLOG2DEV (y2) );
+            LogicalToDeviceX(x1), LogicalToDeviceY(y1),
+            LogicalToDeviceX(x2), LogicalToDeviceY (y2) );
 
     CalcBoundingBox( x1, y1 );
     CalcBoundingBox( x2, y2 );
@@ -521,8 +544,8 @@ void wxPostScriptDC::DoDrawArc (wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
                 "%d %d lineto\n"
                 "closepath\n"
                 "fill\n",
-                XLOG2DEV(xc), YLOG2DEV(yc), XLOG2DEVREL(radius), YLOG2DEVREL(radius), (wxCoord)alpha1, (wxCoord) alpha2,
-                XLOG2DEV(xc), YLOG2DEV(yc) );
+                LogicalToDeviceX(xc), LogicalToDeviceY(yc), LogicalToDeviceXRel(radius), LogicalToDeviceYRel(radius), (wxCoord)alpha1, (wxCoord) alpha2,
+                LogicalToDeviceX(xc), LogicalToDeviceY(yc) );
 
         CalcBoundingBox( xc-radius, yc-radius );
         CalcBoundingBox( xc+radius, yc+radius );
@@ -538,8 +561,8 @@ void wxPostScriptDC::DoDrawArc (wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
                 "%d %d lineto\n"
                 "stroke\n"
                 "fill\n",
-                XLOG2DEV(xc), YLOG2DEV(yc), XLOG2DEVREL(radius), YLOG2DEVREL(radius), (wxCoord)alpha1, (wxCoord) alpha2,
-                XLOG2DEV(xc), YLOG2DEV(yc) );
+                LogicalToDeviceX(xc), LogicalToDeviceY(yc), LogicalToDeviceXRel(radius), LogicalToDeviceYRel(radius), (wxCoord)alpha1, (wxCoord) alpha2,
+                LogicalToDeviceX(xc), LogicalToDeviceY(yc) );
 
         CalcBoundingBox( xc-radius, yc-radius );
         CalcBoundingBox( xc+radius, yc+radius );
@@ -568,7 +591,7 @@ void wxPostScriptDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,d
         fprintf( m_pstream,
                 "newpath\n"
                 "%d %d %d %d %d %d true ellipticarc\n",
-                XLOG2DEV(x+w/2), YLOG2DEV(y+h/2), XLOG2DEVREL(w/2), YLOG2DEVREL(h/2), (wxCoord)sa, (wxCoord)ea );
+                LogicalToDeviceX(x+w/2), LogicalToDeviceY(y+h/2), LogicalToDeviceXRel(w/2), LogicalToDeviceYRel(h/2), (wxCoord)sa, (wxCoord)ea );
 
         CalcBoundingBox( x ,y );
         CalcBoundingBox( x+w, y+h );
@@ -581,7 +604,7 @@ void wxPostScriptDC::DoDrawEllipticArc(wxCoord x,wxCoord y,wxCoord w,wxCoord h,d
         fprintf(m_pstream,
                 "newpath\n"
                 "%d %d %d %d %d %d false ellipticarc\n",
-                XLOG2DEV(x+w/2), YLOG2DEV(y+h/2), XLOG2DEVREL(w/2), YLOG2DEVREL(h/2), (wxCoord)sa, (wxCoord)ea );
+                LogicalToDeviceX(x+w/2), LogicalToDeviceY(y+h/2), LogicalToDeviceXRel(w/2), LogicalToDeviceYRel(h/2), (wxCoord)sa, (wxCoord)ea );
 
         CalcBoundingBox( x ,y );
         CalcBoundingBox( x+w, y+h );
@@ -601,8 +624,8 @@ void wxPostScriptDC::DoDrawPoint (wxCoord x, wxCoord y)
             "%d %d moveto\n"
             "%d %d lineto\n"
             "stroke\n",
-            XLOG2DEV(x),   YLOG2DEV(y),
-            XLOG2DEV(x+1), YLOG2DEV(y) );
+            LogicalToDeviceX(x),   LogicalToDeviceY(y),
+            LogicalToDeviceX(x+1), LogicalToDeviceY(y) );
 
     CalcBoundingBox( x, y );
 }
@@ -619,8 +642,8 @@ void wxPostScriptDC::DoDrawPolygon (int n, wxPoint points[], wxCoord xoffset, wx
 
         fprintf( m_pstream, "newpath\n" );
 
-        wxCoord xx = XLOG2DEV(points[0].x + xoffset);
-        wxCoord yy = YLOG2DEV(points[0].y + yoffset);
+        wxCoord xx = LogicalToDeviceX(points[0].x + xoffset);
+        wxCoord yy = LogicalToDeviceY(points[0].y + yoffset);
 
         fprintf( m_pstream, "%d %d moveto\n", xx, yy );
 
@@ -628,8 +651,8 @@ void wxPostScriptDC::DoDrawPolygon (int n, wxPoint points[], wxCoord xoffset, wx
 
         for (int i = 1; i < n; i++)
         {
-            xx = XLOG2DEV(points[i].x + xoffset);
-            yy = YLOG2DEV(points[i].y + yoffset);
+            xx = LogicalToDeviceX(points[i].x + xoffset);
+            yy = LogicalToDeviceY(points[i].y + yoffset);
 
             fprintf( m_pstream, "%d %d lineto\n", xx, yy );
 
@@ -645,8 +668,8 @@ void wxPostScriptDC::DoDrawPolygon (int n, wxPoint points[], wxCoord xoffset, wx
 
         fprintf( m_pstream, "newpath\n" );
 
-        wxCoord xx = XLOG2DEV(points[0].x + xoffset);
-        wxCoord yy = YLOG2DEV(points[0].y + yoffset);
+        wxCoord xx = LogicalToDeviceX(points[0].x + xoffset);
+        wxCoord yy = LogicalToDeviceY(points[0].y + yoffset);
 
         fprintf( m_pstream, "%d %d moveto\n", xx, yy );
 
@@ -654,8 +677,8 @@ void wxPostScriptDC::DoDrawPolygon (int n, wxPoint points[], wxCoord xoffset, wx
 
         for (int i = 1; i < n; i++)
         {
-            xx = XLOG2DEV(points[i].x + xoffset);
-            yy = YLOG2DEV(points[i].y + yoffset);
+            xx = LogicalToDeviceX(points[i].x + xoffset);
+            yy = LogicalToDeviceY(points[i].y + yoffset);
 
             fprintf( m_pstream, "%d %d lineto\n", xx, yy );
 
@@ -680,19 +703,19 @@ void wxPostScriptDC::DoDrawLines (int n, wxPoint points[], wxCoord xoffset, wxCo
     int i;
     for ( i =0; i<n ; i++ )
     {
-        CalcBoundingBox( XLOG2DEV(points[i].x+xoffset), YLOG2DEV(points[i].y+yoffset));
+        CalcBoundingBox( LogicalToDeviceX(points[i].x+xoffset), LogicalToDeviceY(points[i].y+yoffset));
     }
 
     fprintf( m_pstream,
             "newpath\n"
             "%d %d moveto\n",
-            XLOG2DEV(points[0].x+xoffset), YLOG2DEV(points[0].y+yoffset) );
+            LogicalToDeviceX(points[0].x+xoffset), LogicalToDeviceY(points[0].y+yoffset) );
 
     for (i = 1; i < n; i++)
     {
         fprintf( m_pstream,
                 "%d %d lineto\n",
-                XLOG2DEV(points[i].x+xoffset), YLOG2DEV(points[i].y+yoffset) );
+                LogicalToDeviceX(points[i].x+xoffset), LogicalToDeviceY(points[i].y+yoffset) );
     }
 
     fprintf( m_pstream, "stroke\n" );
@@ -714,10 +737,10 @@ void wxPostScriptDC::DoDrawRectangle (wxCoord x, wxCoord y, wxCoord width, wxCoo
                 "%d %d 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) );
+                LogicalToDeviceX(x),         LogicalToDeviceY(y),
+                LogicalToDeviceX(x + width), LogicalToDeviceY(y),
+                LogicalToDeviceX(x + width), LogicalToDeviceY(y + height),
+                LogicalToDeviceX(x),         LogicalToDeviceY(y + height) );
 
         CalcBoundingBox( x, y );
         CalcBoundingBox( x + width, y + height );
@@ -735,10 +758,10 @@ void wxPostScriptDC::DoDrawRectangle (wxCoord x, wxCoord y, wxCoord width, wxCoo
                 "%d %d 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) );
+                LogicalToDeviceX(x),         LogicalToDeviceY(y),
+                LogicalToDeviceX(x + width), LogicalToDeviceY(y),
+                LogicalToDeviceX(x + width), LogicalToDeviceY(y + height),
+                LogicalToDeviceX(x),         LogicalToDeviceY(y + height) );
 
         CalcBoundingBox( x, y );
         CalcBoundingBox( x + width, y + height );
@@ -780,14 +803,14 @@ void wxPostScriptDC::DoDrawRoundedRectangle (wxCoord x, wxCoord y, wxCoord width
                 "%d %d lineto\n"
                 "closepath\n"
                 "fill\n",
-                XLOG2DEV(x + rad), YLOG2DEV(y + rad), XLOG2DEVREL(rad),
-                XLOG2DEV(x), YLOG2DEV(y + 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) );
+                LogicalToDeviceX(x + rad), LogicalToDeviceY(y + rad), LogicalToDeviceXRel(rad),
+                LogicalToDeviceX(x), LogicalToDeviceY(y + 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) );
 
         CalcBoundingBox( x, y );
         CalcBoundingBox( x + width, y + height );
@@ -810,14 +833,14 @@ void wxPostScriptDC::DoDrawRoundedRectangle (wxCoord x, wxCoord y, wxCoord width
                 "%d %d lineto\n"
                 "closepath\n"
                 "stroke\n",
-                XLOG2DEV(x + rad), YLOG2DEV(y + rad), XLOG2DEVREL(rad),
-                XLOG2DEV(x), YLOG2DEV(y + 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) );
+                LogicalToDeviceX(x + rad), LogicalToDeviceY(y + rad), LogicalToDeviceXRel(rad),
+                LogicalToDeviceX(x), LogicalToDeviceY(y + 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) );
 
         CalcBoundingBox( x, y );
         CalcBoundingBox( x + width, y + height );
@@ -836,8 +859,8 @@ void wxPostScriptDC::DoDrawEllipse (wxCoord x, wxCoord y, wxCoord width, wxCoord
                 "newpath\n"
                 "%d %d %d %d 0 360 ellipse\n"
                 "fill\n",
-                XLOG2DEV(x + width / 2), YLOG2DEV(y + height / 2),
-                XLOG2DEVREL(width / 2), YLOG2DEVREL(height / 2) );
+                LogicalToDeviceX(x + width / 2), LogicalToDeviceY(y + height / 2),
+                LogicalToDeviceXRel(width / 2), LogicalToDeviceYRel(height / 2) );
 
         CalcBoundingBox( x - width, y - height );
         CalcBoundingBox( x + width, y + height );
@@ -851,8 +874,8 @@ void wxPostScriptDC::DoDrawEllipse (wxCoord x, wxCoord y, wxCoord width, wxCoord
                 "newpath\n"
                 "%d %d %d %d 0 360 ellipse\n"
                 "stroke\n",
-                XLOG2DEV(x + width / 2), YLOG2DEV(y + height / 2),
-                XLOG2DEVREL(width / 2), YLOG2DEVREL(height / 2) );
+                LogicalToDeviceX(x + width / 2), LogicalToDeviceY(y + height / 2),
+                LogicalToDeviceXRel(width / 2), LogicalToDeviceYRel(height / 2) );
 
         CalcBoundingBox( x - width, y - height );
         CalcBoundingBox( x + width, y + height );
@@ -881,18 +904,18 @@ void wxPostScriptDC::DoDrawBitmap( const wxBitmap& bitmap, wxCoord x, wxCoord y,
 
     if (!bitmap.Ok()) return;
 
-    wxImage image( bitmap );
+    wxImage image = bitmap.ConvertToImage();
 
     if (!image.Ok()) return;
 
     wxCoord w = image.GetWidth();
     wxCoord h = image.GetHeight();
 
-    wxCoord ww = XLOG2DEVREL(image.GetWidth());
-    wxCoord hh = YLOG2DEVREL(image.GetHeight());
+    wxCoord ww = LogicalToDeviceXRel(image.GetWidth());
+    wxCoord hh = LogicalToDeviceYRel(image.GetHeight());
 
-    wxCoord xx = XLOG2DEV(x);
-    wxCoord yy = YLOG2DEV(y + bitmap.GetHeight());
+    wxCoord xx = LogicalToDeviceX(x);
+    wxCoord yy = LogicalToDeviceY(y + bitmap.GetHeight());
 
     fprintf( m_pstream,
             "/origstate save def\n"
@@ -937,6 +960,7 @@ void wxPostScriptDC::SetFont( const wxFont& font )
 
     m_font = font;
 
+#ifndef __WXGTK20__
     int Style = m_font.GetStyle();
     int Weight = m_font.GetWeight();
 
@@ -1014,13 +1038,14 @@ void wxPostScriptDC::SetFont( const wxFont& font )
     fprintf( m_pstream, " findfont\n" );
 
     char buffer[100];
-    sprintf( buffer, "%f scalefont setfont\n", YLOG2DEVREL(m_font.GetPointSize() * 1000) / 1000.0F);
+    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
-                // YLOG2DEVREL works with wxCoord type (int or longint). Se we first convert font size
+                // 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] = '.';
     fprintf( m_pstream, buffer );
+#endif
 }
 
 void wxPostScriptDC::SetPen( const wxPen& pen )
@@ -1036,9 +1061,9 @@ void wxPostScriptDC::SetPen( const wxPen& pen )
     {
         char buffer[100];
         #ifdef __WXMSW__
-        sprintf( buffer, "%f setlinewidth\n", XLOG2DEVREL(1000 * m_pen.GetWidth()) / 1000.0f );
+        sprintf( buffer, "%f setlinewidth\n", LogicalToDeviceXRel(1000 * m_pen.GetWidth()) / 1000.0f );
         #else
-        sprintf( buffer, "%f setlinewidth\n", XLOG2DEVREL(1000 * m_pen.GetWidth()) / 1000.0f );
+        sprintf( buffer, "%f setlinewidth\n", LogicalToDeviceXRel(1000 * m_pen.GetWidth()) / 1000.0f );
         #endif
         for (int i = 0; i < 100; i++)
             if (buffer[i] == ',') buffer[i] = '.';
@@ -1166,10 +1191,256 @@ void wxPostScriptDC::SetBrush( const wxBrush& brush )
     }
 }
 
+#ifdef __WXGTK20__
+
+#include "wx/gtk/private.h"
+#include "wx/fontutil.h"
+#include "gtk/gtk.h"
+#include <pango/pangoft2.h>
+#include <freetype/ftglyph.h>
+
+#ifndef FT_Outline_Decompose
+  FT_EXPORT( FT_Error )  FT_Outline_Decompose(
+                           FT_Outline*              outline,
+                           const FT_Outline_Funcs*  interface,
+                           void*                    user );
+#endif
+
+typedef struct _OutlineInfo OutlineInfo;
+struct _OutlineInfo {
+  FILE *OUT;
+  FT_Vector glyph_origin;
+  int dpi;
+};
+
+static int paps_move_to( FT_Vector* to,
+                        void *user_data)
+{
+  OutlineInfo *outline_info = (OutlineInfo*)user_data;
+  fprintf(outline_info->OUT, "%d %d moveto\n",
+         (int)to->x ,
+         (int)to->y );
+  return 0;
+}
+
+static int paps_line_to( FT_Vector*  to,
+                        void *user_data)
+{
+  OutlineInfo *outline_info = (OutlineInfo*)user_data;
+  fprintf(outline_info->OUT, "%d %d lineto\n",
+         (int)to->x ,
+         (int)to->y );
+  return 0;
+}
+
+static int paps_conic_to( FT_Vector*  control,
+                         FT_Vector*  to,
+                         void *user_data)
+{
+  OutlineInfo *outline_info = (OutlineInfo*)user_data;
+  fprintf(outline_info->OUT, "%d %d %d %d conicto\n",
+         (int)control->x  ,
+         (int)control->y  ,
+         (int)to->x   ,
+         (int)to->y  );
+  return 0;
+}
+
+static int paps_cubic_to( FT_Vector*  control1,
+                         FT_Vector*  control2,
+                         FT_Vector*  to,
+                         void *user_data)
+{
+  OutlineInfo *outline_info = (OutlineInfo*)user_data;
+  fprintf(outline_info->OUT,
+         "%d %d %d %d %d %d curveto\n",
+         (int)control1->x , 
+         (int)control1->y ,
+         (int)control2->x ,
+         (int)control2->y ,
+         (int)to->x ,
+         (int)to->y );
+  return 0;
+}
+
+static void draw_bezier_outline(FILE *OUT,
+                        int dpi,
+                        FT_Face face,
+                        FT_UInt glyph_index,
+                        wxCoord pos_x,
+                        wxCoord pos_y
+                        )
+{
+  FT_Int load_flags = FT_LOAD_DEFAULT;
+  FT_Glyph glyph;
+
+  /* Output outline */
+  FT_Outline_Funcs outlinefunc = 
+  {
+    paps_move_to,
+    paps_line_to,
+    paps_conic_to,
+    paps_cubic_to
+  };
+  OutlineInfo outline_info;
+
+  outline_info.glyph_origin.x = (FT_Pos) pos_x;
+  outline_info.glyph_origin.y = (FT_Pos) pos_y;
+  outline_info.dpi = dpi;
+  outline_info.OUT = OUT;
+
+  fprintf(OUT, "gsave %d %d translate 0 0 0 setrgbcolor\n", pos_x, pos_y);
+  fprintf(OUT, "start_ol\n");
+
+  FT_Load_Glyph(face, glyph_index, load_flags);
+  FT_Get_Glyph (face->glyph, &glyph);
+  FT_Outline_Decompose (&(((FT_OutlineGlyph)glyph)->outline),
+                        &outlinefunc, &outline_info);
+  fprintf(OUT, "end_ol grestore \n");
+  
+  FT_Done_Glyph (glyph);
+}
+
+
+#endif
+
 void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
 {
     wxCHECK_RET( m_ok && m_pstream, wxT("invalid postscript dc") );
 
+#ifdef __WXGTK20__
+    int dpi = GetResolution() * 2;
+
+    PangoContext *context = pango_ft2_get_context ( dpi, dpi );
+
+    // What are these for?
+    pango_context_set_language (context, pango_language_from_string ("en_US"));
+    pango_context_set_base_dir (context, PANGO_DIRECTION_LTR );
+
+    // Set the font
+    pango_context_set_font_description (context, m_font.GetNativeFontInfo()->description );
+
+    // Create layout 
+    PangoLayout *layout = layout = pango_layout_new (context);
+#if wxUSE_UNICODE
+    wxCharBuffer buffer = wxConvUTF8.cWC2MB( text );
+#else
+    wxCharBuffer buffer = wxConvUTF8.cWC2MB( wxConvLocal.cWX2WC( text ) );
+#endif
+       pango_layout_set_text( layout, (const char*) buffer, strlen(buffer) );
+
+#if 1
+    double xx = LogicalToDeviceX(x);
+    double yy = LogicalToDeviceY(y /*+ bitmap.GetHeight()*/ );
+
+    // Loop over lines in layout
+    int num_lines = pango_layout_get_line_count( layout );
+    for (int i = 0; i < num_lines; i++)
+    {
+        PangoLayoutLine *line = pango_layout_get_line( layout, i );
+        
+        // Loop over runs in line
+        GSList *runs_list = line->runs;
+        while (runs_list)
+        {
+            PangoLayoutRun *run = (PangoLayoutRun*) runs_list->data;
+            PangoItem *item = run->item;
+            PangoGlyphString *glyphs = run->glyphs;
+            PangoAnalysis *analysis = &item->analysis;
+            PangoFont *font = analysis->font;
+            FT_Face ft_face = pango_ft2_font_get_face(font);
+            
+            int num_glyphs = glyphs->num_glyphs;
+            for (int glyph_idx = 0; glyph_idx < num_glyphs; glyph_idx++)
+            {
+                PangoGlyphGeometry geometry = glyphs->glyphs[glyph_idx].geometry;
+                double pos_x = xx + 1.0 * geometry.x_offset / PANGO_SCALE;   
+                double pos_y = yy - 1.0 * geometry.y_offset / PANGO_SCALE;
+                xx += 1.0 * geometry.width / PANGO_SCALE;
+
+                draw_bezier_outline( m_pstream, dpi, ft_face,
+                             (FT_UInt)(glyphs->glyphs[glyph_idx].glyph),
+                             (wxCoord)pos_x, (wxCoord)pos_y );
+            }
+            runs_list = runs_list->next;
+        }
+       }
+#else    
+    // Find out extent for the bitmap
+    int height = 0;
+    int width = 0;
+    PangoRectangle logical_rect;
+    pango_layout_get_extents (layout, NULL, &logical_rect);
+    height = PANGO_PIXELS (logical_rect.height);
+    width = PANGO_PIXELS (logical_rect.width);
+    
+    // printf( "h %d w %d lh %d lw %d\n", height, width, logical_rect.height, logical_rect.width );
+
+    // Allocate FreeType 2 bitmap
+    int byte_width = (width + 7)/8 * 8;
+    FT_Bitmap bitmap;
+    guchar *buf = (guchar*) g_malloc (byte_width * height);
+    memset (buf, 0x00, byte_width * height);
+    bitmap.rows = height;
+    bitmap.width = byte_width;
+       bitmap.pitch = byte_width;
+       bitmap.buffer = buf;
+       bitmap.num_grays = 256;
+       bitmap.pixel_mode = ft_pixel_mode_grays;
+       
+    // Render bitmap
+       pango_ft2_render_layout (&bitmap, layout, 0, 0);
+
+       // Invert bitmap to get black text on white background
+    for (int pix_idx = 0; pix_idx < width * height; pix_idx++)
+        buf[pix_idx] = 255-buf[pix_idx];
+
+    // Write PS output
+    wxCoord xx = LogicalToDeviceX(x);
+    wxCoord yy = LogicalToDeviceY(y /*+ bitmap.GetHeight()*/ );
+
+    fprintf(m_pstream, "gsave\n");
+    fprintf(m_pstream, "%d %d translate\n", xx, yy);
+    fprintf(m_pstream, "/img_width %d def\n", bitmap.width);
+    fprintf(m_pstream, "/img_height %d def\n", bitmap.rows);
+    fprintf(m_pstream, "/picstr img_width 8 idiv string def\n");
+
+    fprintf(m_pstream,
+         "  img_width 72 15 div mul\n"
+          "  img_height 72 15 div mul scale\n"
+         "  0 setgray\n"
+         "  img_width img_height\n"
+         "  true\n"
+         "  [img_width 0 0 img_height neg 0 img_height 0.67 mul]\n"
+         "  { currentfile\n"
+         "    picstr readhexstring pop }\n"
+         "  imagemask"
+         );
+
+
+    for (int b_idx= 0; b_idx < bitmap.width/8 * bitmap.rows; b_idx++)
+    {
+      guchar packed_b = 0;
+      int bit_idx;
+
+      if (b_idx % (bitmap.width/8) == 0)
+       fprintf(m_pstream, "\n");
+      
+      for (bit_idx = 0; bit_idx < 8; bit_idx++)
+       {
+         guchar this_bit = bitmap.buffer[b_idx * 8+bit_idx]<128;
+         packed_b = (packed_b << 1) + this_bit;
+       }
+      fprintf(m_pstream, "%02x", packed_b);
+    }
+  
+    fprintf(m_pstream, "\ngrestore\n" );
+    
+    // Free memory
+    g_free( buf );
+#endif
+
+#else
     wxCoord text_w, text_h, text_descent;
 
     GetTextExtent(text, &text_w, &text_h, &text_descent);
@@ -1224,12 +1495,12 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
 //    commented by V. Slavik and replaced by accurate version
 //        - note that there is still rounding error in text_descent!
     wxCoord by = y + size - text_descent; // baseline
-    fprintf( m_pstream, "%d %d moveto\n", XLOG2DEV(x), YLOG2DEV(by) );
+    fprintf( m_pstream, "%d %d moveto\n", LogicalToDeviceX(x), LogicalToDeviceY(by) );
 
     fprintf( m_pstream, "(" );
     const wxWX2MBbuf textbuf = text.mb_str();
-    int len = strlen(textbuf);
-    int i;
+    size_t len = strlen(textbuf);
+    size_t i;
     for (i = 0; i < len; i++)
     {
         int c = (unsigned char) textbuf[i];
@@ -1264,9 +1535,9 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
                 "%d %d lineto\n"
                 "stroke\n"
                 "grestore\n",
-                XLOG2DEV(x), YLOG2DEV(uy),
+                LogicalToDeviceX(x), LogicalToDeviceY(uy),
                 m_underlineThickness,
-                XLOG2DEV(x + text_w), YLOG2DEV(uy) );
+                LogicalToDeviceX(x + text_w), LogicalToDeviceY(uy) );
         for (i = 0; i < 100; i++)
             if (buffer[i] == ',') buffer[i] = '.';
         fprintf( m_pstream, buffer );
@@ -1274,6 +1545,7 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
 
     CalcBoundingBox( x, y );
     CalcBoundingBox( x + size * text.Length() * 2/3 , y );
+#endif
 }
 
 void wxPostScriptDC::DoDrawRotatedText( const wxString& text, wxCoord x, wxCoord y, double angle )
@@ -1334,18 +1606,18 @@ void wxPostScriptDC::DoDrawRotatedText( const wxString& text, wxCoord x, wxCoord
 
     // FIXME only correct for 90 degrees
     fprintf(m_pstream, "%d %d moveto\n",
-            XLOG2DEV((wxCoord)(x + size)), YLOG2DEV((wxCoord)by) );
+            LogicalToDeviceX((wxCoord)(x + size)), LogicalToDeviceY((wxCoord)by) );
 
     char buffer[100];
     sprintf(buffer, "%.8f rotate\n", angle);
-    int i;
+    size_t i;
     for (i = 0; i < 100; i++)
         if (buffer[i] == ',') buffer[i] = '.';
     fprintf(m_pstream, buffer);
 
     fprintf( m_pstream, "(" );
     const wxWX2MBbuf textbuf = text.mb_str();
-    int len = strlen(textbuf);
+    size_t len = strlen(textbuf);
     for (i = 0; i < len; i++)
     {
         int c = (unsigned char) textbuf[i];
@@ -1387,9 +1659,9 @@ void wxPostScriptDC::DoDrawRotatedText( const wxString& text, wxCoord x, wxCoord
                  "%d %d lineto\n"
                  "stroke\n"
                  "grestore\n",
-                 XLOG2DEV(x), YLOG2DEV(uy),
+                 LogicalToDeviceX(x), LogicalToDeviceY(uy),
                  m_underlineThickness,
-                 XLOG2DEV(x + w), YLOG2DEV(uy) );
+                 LogicalToDeviceX(x + w), LogicalToDeviceY(uy) );
         for (i = 0; i < 100; i++)
             if (buffer[i] == ',') buffer[i] = '.';
         fprintf( m_pstream, buffer );
@@ -1434,8 +1706,8 @@ void wxPostScriptDC::DoDrawSpline( wxList *points )
             "newpath\n"
             "%d %d moveto\n"
             "%d %d lineto\n",
-            XLOG2DEV((wxCoord)x1), YLOG2DEV((wxCoord)y1),
-            XLOG2DEV((wxCoord)x3), YLOG2DEV((wxCoord)y3) );
+            LogicalToDeviceX((wxCoord)x1), LogicalToDeviceY((wxCoord)y1),
+            LogicalToDeviceX((wxCoord)x3), LogicalToDeviceY((wxCoord)y3) );
 
     CalcBoundingBox( (wxCoord)x1, (wxCoord)y1 );
     CalcBoundingBox( (wxCoord)x3, (wxCoord)y3 );
@@ -1455,9 +1727,9 @@ void wxPostScriptDC::DoDrawSpline( wxList *points )
 
         fprintf( m_pstream,
                 "%d %d %d %d %d %d DrawSplineSection\n",
-                XLOG2DEV((wxCoord)x1), YLOG2DEV((wxCoord)y1),
-                XLOG2DEV((wxCoord)x2), YLOG2DEV((wxCoord)y2),
-                XLOG2DEV((wxCoord)x3), YLOG2DEV((wxCoord)y3) );
+                LogicalToDeviceX((wxCoord)x1), LogicalToDeviceY((wxCoord)y1),
+                LogicalToDeviceX((wxCoord)x2), LogicalToDeviceY((wxCoord)y2),
+                LogicalToDeviceX((wxCoord)x3), LogicalToDeviceY((wxCoord)y3) );
 
         CalcBoundingBox( (wxCoord)x1, (wxCoord)y1 );
         CalcBoundingBox( (wxCoord)x3, (wxCoord)y3 );
@@ -1471,7 +1743,7 @@ void wxPostScriptDC::DoDrawSpline( wxList *points )
     fprintf( m_pstream,
             "%d %d lineto\n"
             "stroke\n",
-            XLOG2DEV((wxCoord)c), YLOG2DEV((wxCoord)d) );
+            LogicalToDeviceX((wxCoord)c), LogicalToDeviceY((wxCoord)d) );
 }
 
 wxCoord wxPostScriptDC::GetCharWidth() const
@@ -1577,7 +1849,7 @@ bool wxPostScriptDC::StartDoc( const wxString& message )
         m_printData.SetFilename(filename);
     }
 
-    m_pstream = fopen( m_printData.GetFilename().fn_str(), "w+" );
+    m_pstream = wxFopen( m_printData.GetFilename().c_str(), wxT("w+") );  // FIXME: use fn_str() here under Unicode?
 
     if (!m_pstream)
     {
@@ -1589,11 +1861,14 @@ bool wxPostScriptDC::StartDoc( const wxString& message )
     m_ok = TRUE;
 
     fprintf( m_pstream, "%%%%BeginProlog\n" );
+    fprintf( m_pstream, wxPostScriptHeaderConicTo );
     fprintf( m_pstream, wxPostScriptHeaderEllipse );
     fprintf( m_pstream, wxPostScriptHeaderEllipticArc );
     fprintf( m_pstream, wxPostScriptHeaderColourImage );
+#ifndef __WXGTK20__
     fprintf( m_pstream, wxPostScriptHeaderReencodeISO1 );
     fprintf( m_pstream, wxPostScriptHeaderReencodeISO2 );
+#endif
     if (wxPostScriptHeaderSpline)
         fprintf( m_pstream, wxPostScriptHeaderSpline );
     fprintf( m_pstream, "%%%%EndProlog\n" );
@@ -1627,26 +1902,13 @@ void wxPostScriptDC::EndDoc ()
 
     wxChar *header_file = wxGetTempFileName("ps");
 
-    m_pstream = fopen( wxConvFile.cWX2MB(header_file) , "w+" );
+    m_pstream = wxFopen( header_file, wxT("w+") );
 
     fprintf( m_pstream, "%%!PS-Adobe-2.0\n" );                     // PostScript magic strings
     fprintf( m_pstream, "%%%%Title: %s\n", (const char *)m_title.mb_str() );
-    fprintf( m_pstream, "%%%%Creator: %s\n", (const char*)wxConvCurrent->cWX2MB(wxTheApp->argv[0]) );
+    fprintf( m_pstream, "%%%%Creator: wxWindows PostScript renderer\n" );
     fprintf( m_pstream, "%%%%CreationDate: %s\n", (const char *)wxNow().mb_str() );
 
-    wxChar userID[256];
-    if ( wxGetEmailAddress(userID, sizeof(userID)) )
-    {
-        fprintf( m_pstream, "%%%%For: %s ", wxMBSTRINGCAST wxConvCurrent->cWX2MB(userID) );
-        wxChar userName[245];
-        if (wxGetUserName(userName, sizeof(userName)))
-            fprintf( m_pstream, " (%s)", wxMBSTRINGCAST wxConvCurrent->cWX2MB(userName) );
-        fprintf( m_pstream, "\n" );
-    }
-    else if ( wxGetUserName(userID, sizeof(userID)) )
-    {
-        fprintf( m_pstream, "%%%%For: %s\n", wxMBSTRINGCAST wxConvCurrent->cWX2MB(userID) );;
-    }
 
     // THE FOLLOWING HAS BEEN CONTRIBUTED BY Andy Fyfe <andy@hyperparallel.com>
 
@@ -1666,10 +1928,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) XLOG2DEV(m_minX);
-    wxCoord minY = (wxCoord) YLOG2DEV(m_minY);
-    wxCoord maxX = (wxCoord) XLOG2DEV(m_maxX);
-    wxCoord maxY = (wxCoord) YLOG2DEV(m_maxY);
+    wxCoord minX = (wxCoord) LogicalToDeviceX(m_minX);
+    wxCoord minY = (wxCoord) LogicalToDeviceY(m_minY);
+    wxCoord maxX = (wxCoord) LogicalToDeviceX(m_maxX);
+    wxCoord maxY = (wxCoord) LogicalToDeviceY(m_maxY);
 
     // LOG2DEV may have changed the minimum to maximum vice versa
     if ( minX > maxX ) { wxCoord tmp = minX; minX = maxX; maxX = tmp; }
@@ -1748,7 +2010,10 @@ void wxPostScriptDC::EndDoc ()
                 argv[0] = WXSTRINGCAST previewCommand;
                 argv[1] = WXSTRINGCAST filename;
                 argv[2] = (wxChar*) NULL;
+#if defined(__WXGTK20__) && wxUSE_UNICODE
+#else
                 wxExecute( argv, TRUE );
+#endif
                 wxRemoveFile( m_printData.GetFilename() );
             }
             break;
@@ -1766,7 +2031,10 @@ void wxPostScriptDC::EndDoc ()
 
                 argv[argc++] = WXSTRINGCAST filename;
                 argv[argc++] = (wxChar *) NULL;
+#if defined(__WXGTK20__) && wxUSE_UNICODE
+#else
                 wxExecute( argv, TRUE );
+#endif
                 wxRemoveFile( filename );
             }
             break;
@@ -1957,7 +2225,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
         lastStyle =  Style;
         lastWeight = Weight;
 
-        char *name = (char*) NULL;
+        const char *name = NULL;
 
         switch (Family)
         {
@@ -2034,10 +2302,8 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
            - afmFile = fopen() may fail and in that case the next if branch
            MUST be executed - and it would not if there was "else" */
         {
-           afmName = wxGetInstallPrefix();
+           afmName = wxGetDataDir();
            afmName <<  wxFILE_SEP_PATH
-                   << wxT("share") << wxFILE_SEP_PATH
-                   << wxT("wx") << wxFILE_SEP_PATH
 #if defined(__LINUX__) || defined(__FREEBSD__)
                    << wxT("gs_afm") << wxFILE_SEP_PATH
 #else
@@ -2050,7 +2316,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
 
         if (afmFile==NULL)
         {
-            wxLogDebug( wxT("GetTextExtent: can't open AFM file '%hs'"), afmName.c_str() );
+            wxLogDebug( wxT("GetTextExtent: can't open AFM file '%s'"), afmName.c_str() );
             wxLogDebug( wxT("               using approximate values"));
             for (int i=0; i<256; i++) lastWidths[i] = 500; /* an approximate value */
             lastDescender = -150; /* dito. */
@@ -2073,7 +2339,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                     if ((sscanf(line,"%s%d",descString,&lastDescender)!=2) ||
                             (strcmp(descString,"Descender")!=0))
                     {
-                        wxLogDebug( wxT("AFM-file '%hs': line '%hs' has error (bad descender)"), afmName.c_str(),line );
+                        wxLogDebug( wxT("AFM-file '%s': line '%s' has error (bad descender)"), afmName.c_str(),line );
                     }
                 }
                 /* JC 1.) check for UnderlinePosition */
@@ -2082,7 +2348,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                     if ((sscanf(line,"%s%lf",upString,&UnderlinePosition)!=2) ||
                             (strcmp(upString,"UnderlinePosition")!=0))
                     {
-                        wxLogDebug( wxT("AFM-file '%hs': line '%hs' has error (bad UnderlinePosition)"), afmName.c_str(), line );
+                        wxLogDebug( wxT("AFM-file '%s': line '%s' has error (bad UnderlinePosition)"), afmName.c_str(), line );
                     }
                 }
                 /* JC 2.) check for UnderlineThickness */
@@ -2091,7 +2357,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                     if ((sscanf(line,"%s%lf",utString,&UnderlineThickness)!=2) ||
                             (strcmp(utString,"UnderlineThickness")!=0))
                     {
-                        wxLogDebug( wxT("AFM-file '%hs': line '%hs' has error (bad UnderlineThickness)"), afmName.c_str(), line );
+                        wxLogDebug( wxT("AFM-file '%s': line '%s' has error (bad UnderlineThickness)"), afmName.c_str(), line );
                     }
                 }
                 /* JC 3.) check for EncodingScheme */
@@ -2100,11 +2366,11 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                     if ((sscanf(line,"%s%s",utString,encString)!=2) ||
                             (strcmp(utString,"EncodingScheme")!=0))
                     {
-                        wxLogDebug( wxT("AFM-file '%hs': line '%hs' has error (bad EncodingScheme)"), afmName.c_str(), line );
+                        wxLogDebug( wxT("AFM-file '%s': line '%s' has error (bad EncodingScheme)"), afmName.c_str(), line );
                     }
                     else if (strncmp(encString, "AdobeStandardEncoding", 21))
                     {
-                        wxLogDebug( wxT("AFM-file '%hs': line '%hs' has error (unsupported EncodingScheme %hs)"),
+                        wxLogDebug( wxT("AFM-file '%s': line '%s' has error (unsupported EncodingScheme %s)"),
                                 afmName.c_str(),line, encString);
                     }
                 }
@@ -2113,11 +2379,11 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                 {
                     if (sscanf(line,"%s%d%s%s%d",cString,&ascii,semiString,WXString,&cWidth)!=5)
                     {
-                        wxLogDebug(wxT("AFM-file '%hs': line '%hs' has an error (bad character width)"),afmName.c_str(),line);
+                        wxLogDebug(wxT("AFM-file '%s': line '%s' has an error (bad character width)"),afmName.c_str(),line);
                     }
                     if(strcmp(cString,"C")!=0 || strcmp(semiString,";")!=0 || strcmp(WXString,"WX")!=0)
                     {
-                        wxLogDebug(wxT("AFM-file '%hs': line '%hs' has a format error"),afmName.c_str(),line);
+                        wxLogDebug(wxT("AFM-file '%s': line '%s' has a format error"),afmName.c_str(),line);
                     }
                     /* printf("            char '%c'=%d has width '%d'\n",ascii,ascii,cWidth); */
                     if (ascii>=0 && ascii<256)
@@ -2151,9 +2417,9 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
         // VS: dirty, but is there any better solution?
         double *pt;
         pt = (double*) &m_underlinePosition;
-        *pt = YLOG2DEVREL((wxCoord)(UnderlinePosition * fontToUse->GetPointSize())) / 1000.0f;
+        *pt = LogicalToDeviceYRel((wxCoord)(UnderlinePosition * fontToUse->GetPointSize())) / 1000.0f;
         pt = (double*) &m_underlineThickness;
-        *pt = YLOG2DEVREL((wxCoord)(UnderlineThickness * fontToUse->GetPointSize())) / 1000.0f;
+        *pt = LogicalToDeviceYRel((wxCoord)(UnderlineThickness * fontToUse->GetPointSize())) / 1000.0f;
 
     }
 
@@ -2169,7 +2435,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
     {
         if(lastWidths[*p]== INT_MIN)
         {
-            wxLogDebug(wxT("GetTextExtent: undefined width for character '%hc' (%d)"), *p,*p);
+            wxLogDebug(wxT("GetTextExtent: undefined width for character '%c' (%d)"), *p,*p);
             sum += lastWidths[' ']; /* assume space */
         }
         else