• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

wxwidgets_dc.cpp

Go to the documentation of this file.
00001 // $Id: wxwidgets_dc.cpp 11760 2011-06-01 19:29:11Z airwin $
00002 //
00003 // Copyright (C) 2005  Werner Smekal, Sjaak Verdoold
00004 // Copyright (C) 2005  Germain Carrera Corraleche
00005 // Copyright (C) 1999  Frank Huebner
00006 //
00007 // This file is part of PLplot.
00008 //
00009 // PLplot is free software; you can redistribute it and/or modify
00010 // it under the terms of the GNU Library General Public License as published
00011 // by the Free Software Foundation; either version 2 of the License, or
00012 // (at your option) any later version.
00013 //
00014 // PLplot is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU Library General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU Library General Public License
00020 // along with PLplot; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00022 //
00023 
00024 // TODO:
00025 // - text clipping
00026 // - implement AddToClipRegion for text correctly
00027 //
00028 
00029 // wxwidgets headers
00030 #include <wx/wx.h>
00031 
00032 #include "plDevs.h"
00033 
00034 // plplot headers
00035 #include "plplotP.h"
00036 
00037 // std and driver headers
00038 #include <cmath>
00039 #include "wxwidgets.h"
00040 
00041 
00042 //--------------------------------------------------------------------------
00043 //  wxPLDevDC::wxPLDevDC( void )
00044 //
00045 //  Constructor of the standard wxWidgets device based on the wxPLDevBase
00046 //  class. Only some initialisations are done.
00047 //--------------------------------------------------------------------------
00048 wxPLDevDC::wxPLDevDC( void ) : wxPLDevBase( wxBACKEND_DC )
00049 {
00050     m_dc       = NULL;
00051     m_bitmap   = NULL;
00052     m_font     = NULL;
00053     underlined = false;
00054 }
00055 
00056 
00057 //--------------------------------------------------------------------------
00058 //  wxPLDevDC::~wxPLDevDC( void )
00059 //
00060 //  The deconstructor frees memory allocated by the device.
00061 //--------------------------------------------------------------------------
00062 wxPLDevDC::~wxPLDevDC()
00063 {
00064     if ( ownGUI )
00065     {
00066         if ( m_dc )
00067         {
00068             ( (wxMemoryDC *) m_dc )->SelectObject( wxNullBitmap );
00069             delete m_dc;
00070         }
00071         if ( m_bitmap )
00072             delete m_bitmap;
00073     }
00074 
00075     if ( m_font )
00076         delete m_font;
00077 }
00078 
00079 
00080 //--------------------------------------------------------------------------
00081 //  void wxPLDevDC::DrawLine( short x1a, short y1a, short x2a, short y2a )
00082 //
00083 //  Draw a line from (x1a, y1a) to (x2a, y2a).
00084 //--------------------------------------------------------------------------
00085 void wxPLDevDC::DrawLine( short x1a, short y1a, short x2a, short y2a )
00086 {
00087     x1a = (short) ( x1a / scalex ); y1a = (short) ( height - y1a / scaley );
00088     x2a = (short) ( x2a / scalex );        y2a = (short) ( height - y2a / scaley );
00089 
00090     m_dc->DrawLine( (wxCoord) x1a, (wxCoord) y1a, (wxCoord) x2a, (wxCoord) y2a );
00091 
00092     AddtoClipRegion( (int) x1a, (int) y1a, (int) x2a, (int) y2a );
00093 }
00094 
00095 
00096 //--------------------------------------------------------------------------
00097 //  void wxPLDevDC::DrawPolyline( short *xa, short *ya, PLINT npts )
00098 //
00099 //  Draw a poly line - coordinates are in the xa and ya arrays.
00100 //--------------------------------------------------------------------------
00101 void wxPLDevDC::DrawPolyline( short *xa, short *ya, PLINT npts )
00102 {
00103     wxCoord x1a, y1a, x2a, y2a;
00104 
00105     x2a = (wxCoord) ( xa[0] / scalex );
00106     y2a = (wxCoord) ( height - ya[0] / scaley );
00107     for ( PLINT i = 1; i < npts; i++ )
00108     {
00109         x1a = x2a; y1a = y2a;
00110         x2a = (wxCoord) ( xa[i] / scalex );
00111         y2a = (wxCoord) ( height - ya[i] / scaley );
00112 
00113         m_dc->DrawLine( x1a, y1a, x2a, y2a );
00114 
00115         AddtoClipRegion( (int) x1a, (int) y1a, (int) x2a, (int) y2a );
00116     }
00117 }
00118 
00119 
00120 //--------------------------------------------------------------------------
00121 //  void wxPLDevDC::ClearBackground( PLINT bgr, PLINT bgg, PLINT bgb,
00122 //                                   PLINT x1, PLINT y1, PLINT x2, PLINT y2 )
00123 //
00124 //  Clear parts ((x1,y1) to (x2,y2)) of the background in color (bgr,bgg,bgb).
00125 //--------------------------------------------------------------------------
00126 void wxPLDevDC::ClearBackground( PLINT bgr, PLINT bgg, PLINT bgb,
00127                                  PLINT x1, PLINT y1, PLINT x2, PLINT y2 )
00128 {
00129     if ( x1 < 0 )
00130         x1 = 0;
00131     else
00132         x1 = (PLINT) ( x1 / scalex );
00133     if ( y1 < 0 )
00134         y1 = 0;
00135     else
00136         y1 = (PLINT) ( height - y1 / scaley );
00137     if ( x2 < 0 )
00138         x2 = width;
00139     else
00140         x2 = (PLINT) ( x2 / scalex );
00141     if ( y2 < 0 )
00142         y2 = height;
00143     else
00144         y2 = (PLINT) ( height - y2 / scaley );
00145 
00146     const wxPen   oldPen   = m_dc->GetPen();
00147     const wxBrush oldBrush = m_dc->GetBrush();
00148 
00149     m_dc->SetPen( *( wxThePenList->FindOrCreatePen( wxColour( bgr, bgg, bgb ), 1, wxSOLID ) ) );
00150     m_dc->SetBrush( wxBrush( wxColour( bgr, bgg, bgb ) ) );
00151     m_dc->DrawRectangle( x1, y1, x2 - x1, y2 - y1 );
00152 
00153     m_dc->SetPen( oldPen );
00154     m_dc->SetBrush( oldBrush );
00155 
00156     AddtoClipRegion( x1, y1, x2, y2 );
00157 }
00158 
00159 
00160 //--------------------------------------------------------------------------
00161 //  void wxPLDevDC::FillPolygon( PLStream *pls )
00162 //
00163 //  Draw a filled polygon.
00164 //--------------------------------------------------------------------------
00165 void wxPLDevDC::FillPolygon( PLStream *pls )
00166 {
00167     wxPoint *points = new wxPoint[pls->dev_npts];
00168 
00169     for ( int i = 0; i < pls->dev_npts; i++ )
00170     {
00171         points[i].x = (int) ( pls->dev_x[i] / scalex );
00172         points[i].y = (int) ( height - pls->dev_y[i] / scaley );
00173         if ( i > 0 )
00174             AddtoClipRegion( points[i - 1].x, points[i - 1].y, points[i].x, points[i].y );
00175     }
00176 
00177     if ( pls->dev_eofill )
00178     {
00179         m_dc->DrawPolygon( pls->dev_npts, points, wxODDEVEN_RULE );
00180     }
00181     else
00182     {
00183         m_dc->DrawPolygon( pls->dev_npts, points, wxWINDING_RULE );
00184     }
00185     delete[] points;
00186 }
00187 
00188 
00189 //--------------------------------------------------------------------------
00190 //  void wxPLDevDC::BlitRectangle( wxDC* dc, int vX, int vY,
00191 //                                 int vW, int vH )
00192 //
00193 //  Copy/Blit a rectangle ((vX,vY) to (vX+vW,vY+vH)) into given dc.
00194 //--------------------------------------------------------------------------
00195 void wxPLDevDC::BlitRectangle( wxDC* dc, int vX, int vY, int vW, int vH )
00196 {
00197     if ( m_dc )
00198         dc->Blit( vX, vY, vW, vH, m_dc, vX, vY );
00199 }
00200 
00201 
00202 //--------------------------------------------------------------------------
00203 //  void wxPLDevDC::CreateCanvas( void )
00204 //
00205 //  Create canvas (bitmap and dc) if the driver provides the GUI.
00206 //--------------------------------------------------------------------------
00207 void wxPLDevDC::CreateCanvas()
00208 {
00209     if ( ownGUI )
00210     {
00211         if ( !m_dc )
00212             m_dc = new wxMemoryDC();
00213 
00214         ( (wxMemoryDC *) m_dc )->SelectObject( wxNullBitmap ); // deselect bitmap
00215         if ( m_bitmap )
00216             delete m_bitmap;
00217         m_bitmap = new wxBitmap( bm_width, bm_height, 32 );
00218         ( (wxMemoryDC *) m_dc )->SelectObject( *m_bitmap ); // select new bitmap
00219     }
00220 }
00221 
00222 
00223 //--------------------------------------------------------------------------
00224 //  void wxPLDevDC::SetWidth( PLStream *pls )
00225 //
00226 //  Set the width of the drawing pen.
00227 //--------------------------------------------------------------------------
00228 void wxPLDevDC::SetWidth( PLStream *pls )
00229 {
00230     m_dc->SetPen( *( wxThePenList->FindOrCreatePen( wxColour( pls->cmap0[pls->icol0].r, pls->cmap0[pls->icol0].g,
00231                              pls->cmap0[pls->icol0].b ),
00232                          pls->width > 0 ? pls->width : 1, wxSOLID ) ) );
00233 }
00234 
00235 
00236 //--------------------------------------------------------------------------
00237 //  void wxPLDevDC::SetColor0( PLStream *pls )
00238 //
00239 //  Set color from colormap 0.
00240 //--------------------------------------------------------------------------
00241 void wxPLDevDC::SetColor0( PLStream *pls )
00242 {
00243     m_dc->SetPen( *( wxThePenList->FindOrCreatePen( wxColour( pls->cmap0[pls->icol0].r, pls->cmap0[pls->icol0].g,
00244                              pls->cmap0[pls->icol0].b ),
00245                          pls->width > 0 ? pls->width : 1, wxSOLID ) ) );
00246     m_dc->SetBrush( wxBrush( wxColour( pls->cmap0[pls->icol0].r, pls->cmap0[pls->icol0].g, pls->cmap0[pls->icol0].b ) ) );
00247 }
00248 
00249 
00250 //--------------------------------------------------------------------------
00251 //  void wxPLDevDC::SetColor1( PLStream *pls )
00252 //
00253 //  Set color from colormap 1.
00254 //--------------------------------------------------------------------------
00255 void wxPLDevDC::SetColor1( PLStream *pls )
00256 {
00257     m_dc->SetPen( *( wxThePenList->FindOrCreatePen( wxColour( pls->curcolor.r, pls->curcolor.g,
00258                              pls->curcolor.b ),
00259                          pls->width > 0 ? pls->width : 1, wxSOLID ) ) );
00260     m_dc->SetBrush( wxBrush( wxColour( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b ) ) );
00261 }
00262 
00263 
00264 //--------------------------------------------------------------------------
00265 //  void wxPLDevDC::SetExternalBuffer( void* dc )
00266 //
00267 //  Adds a dc to the device. In that case, the drivers doesn't provide
00268 //  a GUI.
00269 //--------------------------------------------------------------------------
00270 void wxPLDevDC::SetExternalBuffer( void* dc )
00271 {
00272     m_dc   = (wxDC *) dc; // Add the dc to the device
00273     ready  = true;
00274     ownGUI = false;
00275 }
00276 
00277 
00278 #ifdef HAVE_FREETYPE
00279 
00280 //--------------------------------------------------------------------------
00281 //  void wxPLDevDC::PutPixel( short x, short y, PLINT color )
00282 //
00283 //  Draw a pixel in color color @ (x,y).
00284 //--------------------------------------------------------------------------
00285 void wxPLDevDC::PutPixel( short x, short y, PLINT color )
00286 {
00287     const wxPen oldpen = m_dc->GetPen();
00288     m_dc->SetPen( *( wxThePenList->FindOrCreatePen( wxColour( GetRValue( color ), GetGValue( color ), GetBValue( color ) ),
00289                          1, wxSOLID ) ) );
00290     m_dc->DrawPoint( x, y );
00291     AddtoClipRegion( x, y, x, y );
00292     m_dc->SetPen( oldpen );
00293 }
00294 
00295 
00296 //--------------------------------------------------------------------------
00297 //  void wxPLDevDC::PutPixel( short x, short y )
00298 //
00299 //  Draw a pixel in current color @ (x,y).
00300 //--------------------------------------------------------------------------
00301 void wxPLDevDC::PutPixel( short x, short y )
00302 {
00303     m_dc->DrawPoint( x, y );
00304     AddtoClipRegion( x, y, x, y );
00305 }
00306 
00307 
00308 //--------------------------------------------------------------------------
00309 //  PLINT wxPLDevDC::GetPixel( short x, short y )
00310 //
00311 //  Get color information from pixel @ (x,y).
00312 //--------------------------------------------------------------------------
00313 PLINT wxPLDevDC::GetPixel( short x, short y )
00314 {
00315 #ifdef __WXGTK__
00316     // The GetPixel method is incredible slow for wxGTK. Therefore we set the colour
00317     // always to the background color, since this is the case anyway 99% of the time.
00318     PLINT bgr, bgg, bgb;           // red, green, blue
00319     plgcolbg( &bgr, &bgg, &bgb );  // get background color information
00320     return RGB( bgr, bgg, bgb );
00321 #else
00322     wxColour col;
00323     m_dc->GetPixel( x, y, &col );
00324     return RGB( col.Red(), col.Green(), col.Blue() );
00325 #endif
00326 }
00327 
00328 #endif // HAVE_FREETYPE
00329 
00330 
00331 //--------------------------------------------------------------------------
00332 //  void wxPLDevDC::PSDrawTextToDC( char* utf8_string, bool drawText )
00333 //
00334 //  Draw utf8 text to screen if drawText==true. Otherwise determine
00335 //  width and height of text.
00336 //--------------------------------------------------------------------------
00337 void wxPLDevDC::PSDrawTextToDC( char* utf8_string, bool drawText )
00338 {
00339     wxCoord  w, h, d, l;
00340 
00341     wxString str( wxConvUTF8.cMB2WC( utf8_string ), *wxConvCurrent );
00342     m_dc->GetTextExtent( str, &w, &h, &d, &l );
00343     if ( drawText )
00344         m_dc->DrawRotatedText( str, (wxCoord) ( posX / scalex - yOffset / scaley * sin_rot ),
00345             (wxCoord) ( height - ( posY + yOffset * cos_rot ) / scaley ),
00346             rotation * 180.0 / M_PI );
00347     posX      += (PLINT) ( w * scalex * cos_rot );
00348     posY      += (PLINT) ( w * scaley * sin_rot );
00349     textWidth += w;
00350     textHeight = (wxCoord) ( textHeight > ( h + yOffset / scaley ) ? textHeight : ( h + yOffset / scaley ) );
00351     memset( utf8_string, '\0', max_string_length );
00352 }
00353 
00354 
00355 //--------------------------------------------------------------------------
00356 //  void wxPLDevDC::PSSetFont( PLUNICODE fci )
00357 //
00358 //  Set font defined by fci.
00359 //--------------------------------------------------------------------------
00360 void wxPLDevDC::PSSetFont( PLUNICODE fci )
00361 {
00362     unsigned char fontFamily, fontStyle, fontWeight;
00363 
00364     plP_fci2hex( fci, &fontFamily, PL_FCI_FAMILY );
00365     plP_fci2hex( fci, &fontStyle, PL_FCI_STYLE );
00366     plP_fci2hex( fci, &fontWeight, PL_FCI_WEIGHT );
00367 
00368     if ( m_font )
00369         delete m_font;
00370 
00371     m_font = wxFont::New( (int) ( fontSize * fontScale < 4 ? 4 : fontSize * fontScale ),
00372         fontFamilyLookup[fontFamily],
00373         fontStyleLookup[fontStyle] & fontWeightLookup[fontWeight] );
00374     m_font->SetUnderlined( underlined );
00375     m_dc->SetFont( *m_font );
00376 }
00377 
00378 
00379 //--------------------------------------------------------------------------
00380 //  void wxPLDevDC::ProcessString( PLStream* pls, EscText* args )
00381 //
00382 //  This is the main function which processes the unicode text strings.
00383 //  Font size, rotation and color are set, width and height of the
00384 //  text string is determined and then the string is drawn to the canvas.
00385 //--------------------------------------------------------------------------
00386 void wxPLDevDC::ProcessString( PLStream* pls, EscText* args )
00387 {
00388     // Check that we got unicode, warning message and return if not
00389     if ( args->unicode_array_len == 0 )
00390     {
00391         printf( "Non unicode string passed to the wxWidgets driver, ignoring\n" );
00392         return;
00393     }
00394 
00395     // Check that unicode string isn't longer then the max we allow
00396     if ( args->unicode_array_len >= 500 )
00397     {
00398         printf( "Sorry, the wxWidgets drivers only handles strings of length < %d\n", 500 );
00399         return;
00400     }
00401 
00402     // Calculate the font size (in pixels)
00403     fontSize = pls->chrht * VIRTUAL_PIXELS_PER_MM / scaley * 1.3;
00404 
00405     // Use PLplot core routine to get the corners of the clipping rectangle
00406     PLINT rcx[4], rcy[4];
00407     difilt_clip( rcx, rcy );
00408 
00409     wxPoint cpoints[4];
00410     for ( int i = 0; i < 4; i++ )
00411     {
00412         cpoints[i].x = rcx[i] / scalex;
00413         cpoints[i].y = height - rcy[i] / scaley;
00414     }
00415     wxDCClipper clip( *m_dc, wxRegion( 4, cpoints ) );
00416 
00417     // calculate rotation of text
00418     plRotationShear( args->xform, &rotation, &shear, &stride );
00419     rotation -= pls->diorot * M_PI / 2.0;
00420     cos_rot   = cos( rotation );
00421     sin_rot   = sin( rotation );
00422 
00423     // Set font color
00424     m_dc->SetTextForeground( wxColour( pls->cmap0[pls->icol0].r, pls->cmap0[pls->icol0].g,
00425             pls->cmap0[pls->icol0].b ) );
00426     m_dc->SetTextBackground( wxColour( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b ) );
00427 
00428     posX = args->x;
00429     posY = args->y;
00430     PSDrawText( args->unicode_array, args->unicode_array_len, false );
00431 
00432     posX = (PLINT) ( args->x - ( ( args->just * textWidth ) * cos_rot + ( 0.5 * textHeight ) * sin_rot ) * scalex );
00433     posY = (PLINT) ( args->y - ( ( args->just * textWidth ) * sin_rot - ( 0.5 * textHeight ) * cos_rot ) * scaley );
00434     PSDrawText( args->unicode_array, args->unicode_array_len, true );
00435 
00436     AddtoClipRegion( 0, 0, width, height );
00437 }
00438 
00439 

Generated on Wed Oct 12 2011 20:42:23 for PLplot by  doxygen 1.7.1