]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/dcpsg.cpp
Improved handling of selection/deselection events.
[wxWidgets.git] / src / generic / dcpsg.cpp
index bc5b46d2d2b96450b4ed26d5405ac145cae3fd1e..96b05d4f7cf9a334c35e0f62f5534dfd022d6493 100644 (file)
@@ -46,6 +46,7 @@
 #include "wx/textctrl.h"
 #include "wx/prntbase.h"
 #include "wx/paper.h"
+#include "wx/filefn.h"
 
 #include <math.h>
 
@@ -419,7 +420,7 @@ void wxPostScriptDC::DestroyClippingRegion()
         m_clipping = FALSE;
         fprintf( m_pstream, "grestore\n" );
     }
-    
+
     wxDC::DestroyClippingRegion();
 }
 
@@ -1003,11 +1004,11 @@ void wxPostScriptDC::SetFont( const wxFont& font )
     fprintf( m_pstream, " reencodeISO def\n" );
     fprintf( m_pstream, buffer );
     fprintf( m_pstream, " findfont\n" );
-    #ifdef __WXMSW__
-    fprintf( m_pstream, "%d scalefont setfont\n", YLOG2DEVREL(m_font.GetPointSize()) );
-    #else
-    fprintf( m_pstream, "%d scalefont setfont\n", YLOG2DEVREL(m_font.GetPointSize()) );
-    #endif
+
+    fprintf( m_pstream, "%f scalefont setfont\n", YLOG2DEVREL(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
+                // to 1/1000th of pt and then back.
 }
 
 void wxPostScriptDC::SetPen( const wxPen& pen )
@@ -1142,6 +1143,10 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
 {
     wxCHECK_RET( m_ok && m_pstream, wxT("invalid postscript dc") );
 
+    wxCoord text_w, text_h, text_descent;
+
+    GetTextExtent(text, &text_w, &text_h, &text_descent);
+
     SetFont( m_font );
 
     if (m_textForegroundColour.Ok())
@@ -1182,7 +1187,10 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
 
     int size = m_font.GetPointSize();
 
-    wxCoord by = y + (wxCoord)floor( double(size) * 2.0 / 3.0 ); // approximate baseline
+//    wxCoord by = y + (wxCoord)floor( double(size) * 2.0 / 3.0 ); // approximate baseline
+//    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) );
 
     /* I don't know how to write char to a stream, so I use a mini string */
@@ -1220,8 +1228,6 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
     if (m_font.GetUnderlined())
     {
         wxCoord uy = (wxCoord)(y + size - m_underlinePosition);
-        wxCoord w, h;
-        GetTextExtent(text, &w, &h);
 
         fprintf( m_pstream,
                 "gsave\n"
@@ -1232,13 +1238,124 @@ void wxPostScriptDC::DoDrawText( const wxString& text, wxCoord x, wxCoord y )
                 "grestore\n",
                 XLOG2DEV(x), YLOG2DEV(uy),
                 (wxCoord)m_underlineThickness,
-                XLOG2DEV(x + w), YLOG2DEV(uy) );
+                XLOG2DEV(x + text_w), YLOG2DEV(uy) );
     }
 
     CalcBoundingBox( x, y );
     CalcBoundingBox( x + size * text.Length() * 2/3 , y );
 }
 
+void wxPostScriptDC::DoDrawRotatedText( const wxString& text, wxCoord x, wxCoord y, double angle )
+{
+    if (angle == 0.0)
+    {
+        DoDrawText(text, x, y);
+        return;
+    }
+
+    wxCHECK_RET( m_ok && m_pstream, wxT("invalid postscript dc") );
+
+    SetFont( m_font );
+
+    if (m_textForegroundColour.Ok())
+    {
+        unsigned char red = m_textForegroundColour.Red();
+        unsigned char blue = m_textForegroundColour.Blue();
+        unsigned char green = m_textForegroundColour.Green();
+
+        if (!m_colour)
+        {
+            // Anything not white is black
+            if (! (red == (unsigned char) 255 &&
+                   blue == (unsigned char) 255 &&
+                   green == (unsigned char) 255))
+            {
+                red = (unsigned char) 0;
+                green = (unsigned char) 0;
+                blue = (unsigned char) 0;
+            }
+        }
+
+        // maybe setgray here ?
+        if (!(red == m_currentRed && green == m_currentGreen && blue == m_currentBlue))
+        {
+            double redPS = (double)(red) / 255.0;
+            double bluePS = (double)(blue) / 255.0;
+            double greenPS = (double)(green) / 255.0;
+
+            fprintf( m_pstream,
+                    "%.8f %.8f %.8f setrgbcolor\n",
+                    redPS, greenPS, bluePS );
+
+            m_currentRed = red;
+            m_currentBlue = blue;
+            m_currentGreen = green;
+        }
+    }
+
+    int size = m_font.GetPointSize();
+
+    long by = y + (long)floor( double(size) * 2.0 / 3.0 ); // approximate baseline
+
+    // FIXME only correct for 90 degrees
+    fprintf(m_pstream, "%d %d moveto\n",
+            XLOG2DEV((wxCoord)(x + size)), YLOG2DEV(by) );
+    fprintf(m_pstream, "%.8f rotate\n", angle);
+
+    /* I don't know how to write char to a stream, so I use a mini string */
+    char tmpbuf[2];
+    tmpbuf[1] = 0;
+
+    fprintf( m_pstream, "(" );
+    const wxWX2MBbuf textbuf = text.mb_str();
+    int len = strlen(textbuf);
+    int i;
+    for (i = 0; i < len; i++)
+    {
+        int c = (unsigned char) textbuf[i];
+        if (c == ')' || c == '(' || c == '\\')
+        {
+            /* Cope with special characters */
+            fprintf( m_pstream, "\\" );
+            tmpbuf[0] = (char) c;
+            fprintf( m_pstream, tmpbuf );
+        }
+        else if ( c >= 128 )
+        {
+            /* Cope with character codes > 127 */
+            fprintf(m_pstream, "\\%o", c);
+        }
+        else
+        {
+            tmpbuf[0] = (char) c;
+            fprintf( m_pstream, tmpbuf );
+        }
+    }
+
+    fprintf( m_pstream, ") show\n" );
+    fprintf( m_pstream, "%.8f rotate\n", -angle );
+
+    if (m_font.GetUnderlined())
+    {
+        wxCoord uy = (wxCoord)(y + size - m_underlinePosition);
+        wxCoord w, h;
+        GetTextExtent(text, &w, &h);
+
+        fprintf( m_pstream,
+                 "gsave\n"
+                 "%d %d moveto\n"
+                 "%ld setlinewidth\n"
+                 "%d %d lineto\n"
+                 "stroke\n"
+                 "grestore\n",
+                 XLOG2DEV(x), YLOG2DEV(uy),
+                 (long)m_underlineThickness,
+                 XLOG2DEV(x + w), YLOG2DEV(uy) );
+    }
+
+    CalcBoundingBox( x, y );
+    CalcBoundingBox( x + size * text.Length() * 2/3 , y );
+}
 
 void wxPostScriptDC::SetBackground (const wxBrush& brush)
 {
@@ -1329,8 +1446,8 @@ void wxPostScriptDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
     m_signX = (xLeftRight ? 1 : -1);
     m_signY = (yBottomUp  ? 1 : -1);
 
-    // FIXME there is no such function in MSW
-#ifndef __WXMSW__
+    // FIXME there is no such function in MSW nor in OS2/PM
+#if !defined(__WXMSW__) && !defined(__WXPM__)
     ComputeScaleAndOrigin();
 #endif
 }
@@ -1493,8 +1610,8 @@ void wxPostScriptDC::EndDoc ()
     wxCoord wx_printer_translate_x, wx_printer_translate_y;
     double wx_printer_scale_x, wx_printer_scale_y;
 
-    wx_printer_translate_x = m_printData.GetPrinterTranslateX();
-    wx_printer_translate_y = m_printData.GetPrinterTranslateY();
+    wx_printer_translate_x = (wxCoord)m_printData.GetPrinterTranslateX();
+    wx_printer_translate_y = (wxCoord)m_printData.GetPrinterTranslateY();
 
     wx_printer_scale_x = m_printData.GetPrinterScaleX();
     wx_printer_scale_y = m_printData.GetPrinterScaleY();
@@ -1621,8 +1738,8 @@ void wxPostScriptDC::StartPage()
     wxCoord translate_x, translate_y;
     double scale_x, scale_y;
 
-    translate_x = m_printData.GetPrinterTranslateX();
-    translate_y = m_printData.GetPrinterTranslateY();
+    translate_x = (wxCoord)m_printData.GetPrinterTranslateX();
+    translate_y = (wxCoord)m_printData.GetPrinterTranslateY();
 
     scale_x = m_printData.GetPrinterScaleX();
     scale_y = m_printData.GetPrinterScaleY();
@@ -1785,7 +1902,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                 {
                     if ((Style == wxITALIC) && (Weight == wxBOLD)) name = "CourBoO";
                     else if ((Style != wxITALIC) && (Weight == wxBOLD)) name = "CourBo";
-                    else if ((Style == wxITALIC) && (Weight != wxBOLD)) name = "Cour0";
+                    else if ((Style == wxITALIC) && (Weight != wxBOLD)) name = "CourO";
                     else name = "Cour";
                 }
                 break;
@@ -1801,19 +1918,17 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                 {
                     if ((Style == wxITALIC) && (Weight == wxBOLD)) name = "HelvBoO";
                     else if ((Style != wxITALIC) && (Weight == wxBOLD)) name = "HelvBo";
-                    else if ((Style == wxITALIC) && (Weight != wxBOLD)) name = "Helv0";
+                    else if ((Style == wxITALIC) && (Weight != wxBOLD)) name = "HelvO";
                     else name = "Helv";
                 }
                 break;
         }
 
         /* get the directory of the AFM files */
-        char afmName[256];
-        afmName[0] = 0;
-
+        wxString afmName = wxEmptyString;
         if (!m_printData.GetFontMetricPath().IsEmpty())
         {
-            strcpy( afmName, m_printData.GetFontMetricPath().fn_str() );
+            afmName = m_printData.GetFontMetricPath();
         }
 
         /* 2. open and process the file
@@ -1832,32 +1947,37 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
 
         /* new elements JC Sun Aug 25 23:21:44 MET DST 1996 */
 
-        strcat(afmName,name);
-        strcat(afmName,".afm");
-        FILE *afmFile = fopen(afmName,"r");
-
-#ifdef __UNIX__
+        afmName << name << wxT(".afm");
+        FILE *afmFile = wxFopen(afmName,wxT("r"));
         if (afmFile==NULL)
         {
-            strcpy( afmName, "/usr/local/share/wx/afm/" );
-             strcat(afmName,name);
-             strcat(afmName,".afm");
-             afmFile = fopen(afmName,"r");
+           afmName = wxThePrintSetupData->GetAFMPath();
+           afmName << wxFILE_SEP_PATH << name << wxT(".afm");
+           afmFile = wxFopen(afmName,wxT("r"));
         }
 
-        if (afmFile==NULL)
+#ifdef __UNIX__
+#ifndef __VMS__
+       if (afmFile==NULL)
+        /* please do NOT change the line above to "else if (afmFile==NULL)" -
+           - afmFile = fopen() may fail and in that case the next if branch
+           MUST be executed - and it would not if there was "else" */
         {
-            strcpy( afmName, "/usr/share/wx/afm/" );
-            strcat(afmName,name);
-            strcat(afmName,".afm");
-            afmFile = fopen(afmName,"r");
+           afmName = wxINSTALL_PREFIX;
+           afmName <<  wxFILE_SEP_PATH
+                   << wxT("share") << wxFILE_SEP_PATH
+                   << wxT("wx") << wxFILE_SEP_PATH
+                   << wxT("afm") << wxFILE_SEP_PATH
+                   << name << wxT(".afm");
+           afmFile = wxFopen(afmName,wxT("r"));
         }
+#endif
 #endif
 
         if (afmFile==NULL)
         {
-            wxLogDebug( "GetTextExtent: can't open AFM file '%s'\n", afmName );
-            wxLogDebug( "               using approximate values\n");
+            wxLogDebug( wxT("GetTextExtent: can't open AFM file '%hs'\n"), afmName.c_str() );
+            wxLogDebug( wxT("               using approximate values\n"));
             for (int i=0; i<256; i++) lastWidths[i] = 500; /* an approximate value */
             lastDescender = -150; /* dito. */
         }
@@ -1879,7 +1999,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                     if ((sscanf(line,"%s%d",descString,&lastDescender)!=2) ||
                             (strcmp(descString,"Descender")!=0))
                     {
-                        wxLogDebug( "AFM-file '%s': line '%s' has error (bad descender)\n", afmName,line );
+                        wxLogDebug( wxT("AFM-file '%hs': line '%hs' has error (bad descender)\n"), afmName.c_str(),line );
                     }
                 }
                 /* JC 1.) check for UnderlinePosition */
@@ -1888,7 +2008,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                     if ((sscanf(line,"%s%lf",upString,&UnderlinePosition)!=2) ||
                             (strcmp(upString,"UnderlinePosition")!=0))
                     {
-                        wxLogDebug( "AFM-file '%s': line '%s' has error (bad UnderlinePosition)\n", afmName, line );
+                        wxLogDebug( wxT("AFM-file '%hs': line '%hs' has error (bad UnderlinePosition)\n"), afmName.c_str(), line );
                     }
                 }
                 /* JC 2.) check for UnderlineThickness */
@@ -1897,7 +2017,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                     if ((sscanf(line,"%s%lf",utString,&UnderlineThickness)!=2) ||
                             (strcmp(utString,"UnderlineThickness")!=0))
                     {
-                        wxLogDebug( "AFM-file '%s': line '%s' has error (bad UnderlineThickness)\n", afmName, line );
+                        wxLogDebug( wxT("AFM-file '%hs': line '%hs' has error (bad UnderlineThickness)\n"), afmName.c_str(), line );
                     }
                 }
                 /* JC 3.) check for EncodingScheme */
@@ -1906,12 +2026,12 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                     if ((sscanf(line,"%s%s",utString,encString)!=2) ||
                             (strcmp(utString,"EncodingScheme")!=0))
                     {
-                        wxLogDebug("AFM-file '%s': line '%s' has error (bad EncodingScheme)\n", afmName, line );
+                        wxLogDebug( wxT("AFM-file '%hs': line '%hs' has error (bad EncodingScheme)\n"), afmName.c_str(), line );
                     }
                     else if (strncmp(encString, "AdobeStandardEncoding", 21))
                     {
-                        wxLogDebug( "AFM-file '%s': line '%s' has error (unsupported EncodingScheme %s)\n",
-                                afmName,line, encString);
+                        wxLogDebug( wxT("AFM-file '%hs': line '%hs' has error (unsupported EncodingScheme %hs)\n"),
+                                afmName.c_str(),line, encString);
                     }
                 }
                 /* B.) check for char-width */
@@ -1919,11 +2039,11 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                 {
                     if (sscanf(line,"%s%d%s%s%d",cString,&ascii,semiString,WXString,&cWidth)!=5)
                     {
-                        wxLogDebug("AFM-file '%s': line '%s' has an error (bad character width)\n",afmName,line);
+                        wxLogDebug(wxT("AFM-file '%hs': line '%hs' has an error (bad character width)\n"),afmName.c_str(),line);
                     }
                     if(strcmp(cString,"C")!=0 || strcmp(semiString,";")!=0 || strcmp(WXString,"WX")!=0)
                     {
-                        wxLogDebug("AFM-file '%s': line '%s' has a format error\n",afmName,line);
+                        wxLogDebug(wxT("AFM-file '%hs': line '%hs' has a format error\n"),afmName.c_str(),line);
                     }
                     /* printf("            char '%c'=%d has width '%d'\n",ascii,ascii,cWidth); */
                     if (ascii>=0 && ascii<256)
@@ -1933,7 +2053,7 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
                     else
                     {
                         /* MATTHEW: this happens a lot; don't print an error */
-                        /* wxLogDebug("AFM-file '%s': ASCII value %d out of range\n",afmName,ascii); */
+                        /* wxLogDebug("AFM-file '%s': ASCII value %d out of range\n",afmName.c_str(),ascii); */
                     }
                 }
                 /* C.) ignore other entries. */
@@ -1970,24 +2090,26 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
     double widthSum=0;
     wxCoord height=Size; /* by default */
     unsigned char *p;
-    for(p=(unsigned char *)strbuf; *p; p++)
+    for(p=(unsigned char *)wxMBSTRINGCAST strbuf; *p; p++)
     {
         if(lastWidths[*p]== INT_MIN)
         {
-            wxLogDebug("GetTextExtent: undefined width for character '%c' (%d)\n", *p,*p);
-            widthSum += /*(wxCoord)*/(lastWidths[' ']/1000.0F * Size); /* assume space */
+            wxLogDebug(wxT("GetTextExtent: undefined width for character '%hc' (%d)\n"), *p,*p);
+            widthSum += (lastWidths[' ']/1000.0F * Size); /* assume space */
         }
         else
         {
-            widthSum += /*(wxCoord)*/((lastWidths[*p]/1000.0F)*Size);
+            widthSum += ((lastWidths[*p]/1000.0F)*Size);
         }
     }
 
     /* add descender to height (it is usually a negative value) */
-    if (lastDescender != INT_MIN)
-    {
-        height += (wxCoord)(((-lastDescender)/1000.0F) * Size); /* MATTHEW: forgot scale */
-    }
+    //if (lastDescender != INT_MIN)
+    //{
+    //    height += (wxCoord)(((-lastDescender)/1000.0F) * Size); /* MATTHEW: forgot scale */
+    //}
+    // - commented by V. Slavik - height already contains descender in it
+    //   (judging from few experiments)
 
     /* return size values */
     if ( x )
@@ -2035,10 +2157,8 @@ void wxPostScriptDC::DoGetTextExtent(const wxString& string,
 
 wxPrintSetupData *wxThePrintSetupData = (wxPrintSetupData *) NULL;
 
-#if !USE_SHARED_LIBRARY
 IMPLEMENT_DYNAMIC_CLASS(wxPostScriptDC, wxDC)
 IMPLEMENT_DYNAMIC_CLASS(wxPrintSetupData, wxObject)
-#endif
 
 // Redundant now I think
 #if 1