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

wxwidgets_agg.cpp

Go to the documentation of this file.
00001 // $Id: wxwidgets_agg.cpp 11760 2011-06-01 19:29:11Z airwin $
00002 //
00003 // Copyright (C) 2008  Werner Smekal
00004 //
00005 // This file is part of PLplot.
00006 //
00007 // PLplot is free software; you can redistribute it and/or modify
00008 // it under the terms of the GNU Library General Public License as published
00009 // by the Free Software Foundation; either version 2 of the License, or
00010 // (at your option) any later version.
00011 //
00012 // PLplot is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU Library General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU Library General Public License
00018 // along with PLplot; if not, write to the Free Software
00019 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020 //
00021 
00022 // TODO:
00023 // - let the AGG library process the text. In the moment most of the relevant code
00024 //   is commented out, since there are problems with the affine transformation
00025 //
00026 
00027 // wxwidgets headers
00028 #include <wx/wx.h>
00029 #include <wx/strconv.h>
00030 
00031 #include "plDevs.h"
00032 
00033 // plplot headers
00034 #include "plplotP.h"
00035 #include "plfci-truetype.h"
00036 
00037 // std and driver headers
00038 #include "wxwidgets.h"
00039 #include <wchar.h>
00040 
00041 // helper functions
00042 #if !defined ( WIN32 ) || defined ( __GNUC__ )
00043   #include <unistd.h>
00044 #else
00045   #define F_OK    1
00046   #include <stdio.h>
00047 int access( char *filename, int flag )
00048 {
00049     FILE *infile;
00050     infile = fopen( filename, "r" );
00051     if ( infile != NULL )
00052     {
00053         fclose( infile );
00054         return 0;
00055     }
00056     else
00057         return 1;
00058 }
00059 #endif
00060 
00061 #define makeunixslash( b )    do { char *I; for ( I = b; *I != 0; *I++ ) if ( *I == '\\' ) *I = '/';} while ( 0 )
00062 
00063 //--------------------------------------------------------------------------
00064 //  wxPLDevAGG::wxPLDevAGG()
00065 //
00066 //  Constructor of the AGG wxWidgets device based on the wxPLDevBase
00067 //  class. Initialisations of variables and objects are done.
00068 //--------------------------------------------------------------------------
00069 wxPLDevAGG::wxPLDevAGG() :
00070     wxPLDevBase( wxBACKEND_AGG ),
00071     mRenderingBuffer(),
00072     mPixFormat( mRenderingBuffer ),
00073     mRendererBase( mPixFormat ),
00074     mRendererSolid( mRendererBase ),
00075 
00076     mPath(),
00077     mTransform(),
00078     mConvCurve( mPath ),
00079     mConvStroke( mConvCurve ),
00080     mPathTransform( mConvCurve, mTransform ),
00081     mStrokeTransform( mConvStroke, mTransform ),
00082 
00083     mFontEngine(),
00084     mFontManager( mFontEngine ),
00085     mCurves( mFontManager.path_adaptor() ),
00086     mContour( mCurves ),
00087 
00088     mBuffer( NULL ),
00089     mStrokeWidth( 1.0 ),
00090     mStrokeOpacity( 255 ),
00091     mColorRedStroke( 255 ),
00092     mColorGreenStroke( 255 ),
00093     mColorBlueStroke( 255 ),
00094     mColorRedFill( 0 ),
00095     mColorGreenFill( 0 ),
00096     mColorBlueFill( 0 )
00097 {
00098     mCurves.approximation_scale( 2.0 );
00099     mContour.auto_detect_orientation( false );
00100     mConvStroke.line_join( agg::round_join );
00101     mConvStroke.line_cap( agg::round_cap );
00102 
00103     // determine font directory
00104 #if defined ( WIN32 )
00105     //static char *default_font_names[]={"arial.ttf","times.ttf","timesi.ttf","arial.ttf",
00106     //                                 "symbol.ttf"};
00107     // char WINDIR_PATH[255];
00108     // char *b;
00109     // b=getenv("WINDIR");
00110     // strncpy(WINDIR_PATH,b,255);
00111 
00112 //
00113 // Work out if we have Win95+ or Win3.?... sort of.
00114 // Actually, this just tries to find the place where the fonts live by looking
00115 // for arial, which should be on all windows machines.
00116 // At present, it only looks in two places, on one drive. I might change this
00117 // soon.
00118 //
00119     //if (WINDIR_PATH==NULL)
00120     // {
00121     //  if (access("c:\\windows\\fonts\\arial.ttf", F_OK)==0) {
00122     //      strcpy(font_dir,"c:/windows/fonts/");
00123     //  }
00124     //  else if ( access("c:\\windows\\system\\arial.ttf", F_OK)==0) {
00125     //      strcpy(font_dir,"c:/windows/system/");
00126     //  }
00127     //  else
00128     //  plwarn("Could not find font path; I sure hope you have defined fonts manually !");
00129     // }
00130     // else
00131     // {
00132     // strncat(WINDIR_PATH,"\\fonts\\arial.ttf",255);
00133     // if (access(WINDIR_PATH, F_OK)==0)
00134     //  {
00135     //    b=strrchr(WINDIR_PATH,'\\');
00136     //    b++;
00137     //b=0;
00138     //    makeunixslash(WINDIR_PATH);
00139     //    strcpy(font_dir,WINDIR_PATH);
00140     //  }
00141     // else
00142     //  plwarn("Could not find font path; I sure hope you have defined fonts manually !");
00143     // }
00144     //
00145     // if (pls->debug) fprintf( stderr, "%s\n", font_dir ) ;
00146 #else
00147     //  For Unix systems, we will set the font path up a little differently in
00148     //  that the configured PL_FREETYPE_FONT_DIR has been set as the default path,
00149     //  but the user can override this by setting the environmental variable
00150     //  "PLPLOT_FREETYPE_FONT_DIR" to something else.
00151     //  NOTE WELL - the trailing slash must be added for now !
00152     //
00153     // const char *str;
00154     //
00155     // fontdir.Clear();
00156     // if( (str=getenv("PLPLOT_FREETYPE_FONT_DIR"))!=NULL )
00157     //      fontdir.Append( wxString(str, wxConvFile) );
00158     // else
00159     //      fontdir.Append( wxT(PL_FREETYPE_FONT_DIR) );
00160     //
00161     // //printf("fontdir=%s, len=%d\n", fontdir.c_str(), fontdir.Length() );
00162 #endif
00163 }
00164 
00165 
00166 //--------------------------------------------------------------------------
00167 //  wxPLDevAGG::~wxPLDevAGG()
00168 //
00169 //  Deconstructor frees allocated buffer.
00170 //--------------------------------------------------------------------------
00171 wxPLDevAGG::~wxPLDevAGG()
00172 {
00173     if ( ownGUI )
00174         if ( mBuffer )
00175             delete mBuffer;
00176 }
00177 
00178 
00179 //--------------------------------------------------------------------------
00180 //  void wxPLDevAGG::drawPath( drawPathFlag flag )
00181 //
00182 //  Common function which either draws a stroke along a path or a filled
00183 //  polygon surrounded by a stroke depending on flag.
00184 //--------------------------------------------------------------------------
00185 void wxPLDevAGG::drawPath( drawPathFlag flag )
00186 {
00187     mRasterizer.reset();
00188 
00189     switch ( flag )
00190     {
00191     case Stroke:
00192         if ( mStrokeOpacity && mStrokeWidth > 0.0 )
00193         {
00194             mConvStroke.width( mStrokeWidth );
00195             mRasterizer.add_path( mStrokeTransform );
00196             mRendererSolid.color( agg::rgba8( mColorRedStroke, mColorGreenStroke, mColorBlueStroke, mStrokeOpacity ) );
00197             agg::render_scanlines( mRasterizer, mScanLine, mRendererSolid );
00198         }
00199         break;
00200     case FillAndStroke:
00201         if ( mStrokeOpacity )
00202         {
00203             mRasterizer.add_path( mPathTransform );
00204             mRendererSolid.color( agg::rgba8( mColorRedStroke, mColorGreenStroke, mColorBlueStroke, mStrokeOpacity ) );
00205             agg::render_scanlines( mRasterizer, mScanLine, mRendererSolid );
00206         }
00207 
00208         if ( mStrokeOpacity && mStrokeWidth > 0.0 )
00209         {
00210             mConvStroke.width( mStrokeWidth );
00211             mRasterizer.add_path( mStrokeTransform );
00212             mRendererSolid.color( agg::rgba8( mColorRedStroke, mColorGreenStroke, mColorBlueStroke, mStrokeOpacity ) );
00213             agg::render_scanlines( mRasterizer, mScanLine, mRendererSolid );
00214         }
00215         break;
00216     }
00217 }
00218 
00219 
00220 //--------------------------------------------------------------------------
00221 //  void wxPLDevAGG::DrawLine( short x1a, short y1a, short x2a, short y2a )
00222 //
00223 //  Draw a line from (x1a, y1a) to (x2a, y2a).
00224 //--------------------------------------------------------------------------
00225 void wxPLDevAGG::DrawLine( short x1a, short y1a, short x2a, short y2a )
00226 {
00227     mPath.remove_all();
00228     mPath.move_to( x1a, y1a );
00229     mPath.line_to( x2a, y2a );
00230 
00231     if ( !resizing && ownGUI )
00232         AGGAddtoClipRegion( x1a, y1a, x2a, y2a );
00233 
00234     drawPath( Stroke );
00235 }
00236 
00237 
00238 //--------------------------------------------------------------------------
00239 //  void wxPLDevAGG::DrawPolyline( short *xa, short *ya, PLINT npts )
00240 //
00241 //  Draw a poly line - coordinates are in the xa and ya arrays.
00242 //--------------------------------------------------------------------------
00243 void wxPLDevAGG::DrawPolyline( short *xa, short *ya, PLINT npts )
00244 {
00245     mPath.remove_all();
00246     mPath.move_to( xa[0], ya[0] );
00247     for ( PLINT i = 1; i < npts; i++ )
00248     {
00249         mPath.line_to( xa[i], ya[i] );
00250         if ( !resizing && ownGUI )
00251             AGGAddtoClipRegion( xa[i - 1], ya[i - 1], xa[i], ya[i] );
00252     }
00253 
00254     drawPath( Stroke );
00255 }
00256 
00257 
00258 //--------------------------------------------------------------------------
00259 //  void wxPLDevAGG::ClearBackground( PLINT bgr, PLINT bgg, PLINT bgb,
00260 //                                    PLINT x1, PLINT y1, PLINT x2, PLINT y2 )
00261 //
00262 //  Clear parts ((x1,y1) to (x2,y2)) of the background in color (bgr,bgg,bgb).
00263 //--------------------------------------------------------------------------
00264 void wxPLDevAGG::ClearBackground( PLINT bgr, PLINT bgg, PLINT bgb, PLINT x1, PLINT y1, PLINT x2, PLINT y2 )
00265 {
00266     if ( x1 < 0 && y1 < 0 && x2 < 0 && y2 < 0 )
00267     {
00268         mRendererBase.clear( agg::rgba8( bgr, bgg, bgb ) );
00269         if ( !resizing && ownGUI )
00270             AddtoClipRegion( 0, 0, width, height );
00271     }
00272     else
00273     {
00274         mPath.remove_all();
00275         mPath.move_to( x1, y1 );
00276         mPath.line_to( x2, y1 );
00277         mPath.line_to( x2, y2 );
00278         mPath.line_to( x1, y2 );
00279         mPath.close_polygon();
00280 
00281         mRasterizer.reset();
00282         mRasterizer.add_path( mPathTransform );
00283         mRendererSolid.color( agg::rgba8( bgr, bgg, bgb, 255 ) );
00284         agg::render_scanlines( mRasterizer, mScanLine, mRendererSolid );
00285 
00286         mConvStroke.width( 1.0 );
00287         mRasterizer.add_path( mStrokeTransform );
00288         mRendererSolid.color( agg::rgba8( bgr, bgg, bgb, 255 ) );
00289         agg::render_scanlines( mRasterizer, mScanLine, mRendererSolid );
00290 
00291         if ( !resizing && ownGUI )
00292             AGGAddtoClipRegion( x1, y1, x2, y2 );
00293     }
00294 }
00295 
00296 
00297 //--------------------------------------------------------------------------
00298 //  void wxPLDevAGG::AGGAddtoClipRegion( short x1, short y1,
00299 //                                       short x2, short y2 )
00300 //
00301 //  Adds the region (x1,y1)-(x2,y2) to the regions which needs to be
00302 //  updated/redrawn.
00303 //--------------------------------------------------------------------------
00304 void wxPLDevAGG::AGGAddtoClipRegion( short x1, short y1, short x2, short y2 )
00305 {
00306     double x1d = x1, x2d = x2, y1d = y1, y2d = y2;
00307 
00308     mTransform.transform( &x1d, &y1d );
00309     mTransform.transform( &x2d, &y2d );
00310     AddtoClipRegion( (int) floor( x1d ), (int) floor( y1d ), (int) ceil( x2d ), (int) ceil( y2d ) );
00311 }
00312 
00313 
00314 //--------------------------------------------------------------------------
00315 //  void wxPLDevAGG::FillPolygon( PLStream *pls )
00316 //
00317 //  Draw a filled polygon.
00318 //--------------------------------------------------------------------------
00319 void wxPLDevAGG::FillPolygon( PLStream *pls )
00320 {
00321     short *xa = pls->dev_x;
00322     short *ya = pls->dev_y;
00323 
00324     mPath.remove_all();
00325     mPath.move_to( xa[0], ya[0] );
00326     for ( PLINT i = 1; i < pls->dev_npts; i++ )
00327     {
00328         mPath.line_to( xa[i], ya[i] );
00329         if ( !resizing && ownGUI )
00330             AGGAddtoClipRegion( xa[i - 1], ya[i - 1], xa[i], ya[i] );
00331     }
00332     mPath.line_to( xa[0], ya[0] );
00333     mPath.close_polygon();
00334 
00335     drawPath( FillAndStroke );
00336 }
00337 
00338 
00339 //--------------------------------------------------------------------------
00340 //  void wxPLDevAGG::BlitRectangle( wxDC* dc, int vX, int vY,
00341 //                                  int vW, int vH )
00342 //
00343 //  Copy/Blit a rectangle ((vX,vY) to (vX+vW,vY+vH)) into given dc.
00344 //--------------------------------------------------------------------------
00345 void wxPLDevAGG::BlitRectangle( wxDC* dc, int vX, int vY, int vW, int vH )
00346 {
00347     if ( mBuffer )
00348     {
00349         wxMemoryDC MemoryDC;
00350         wxBitmap   bitmap( mBuffer->GetSubImage( wxRect( vX, vY, vW, vH ) ), -1 );
00351         MemoryDC.SelectObject( bitmap );
00352         dc->Blit( vX, vY, vW, vH, &MemoryDC, 0, 0 );
00353         MemoryDC.SelectObject( wxNullBitmap );
00354     }
00355 }
00356 
00357 
00358 //--------------------------------------------------------------------------
00359 //  void wxPLDevAGG::CreateCanvas( void )
00360 //
00361 //  Create canvas (bitmap and dc) if the driver provides the GUI.
00362 //--------------------------------------------------------------------------
00363 void wxPLDevAGG::CreateCanvas()
00364 {
00365     if ( ownGUI )
00366     {
00367         // get a new wxImage (image buffer)
00368         if ( mBuffer )
00369             delete mBuffer;
00370         mBuffer = new wxImage( bm_width, bm_height );
00371         mRenderingBuffer.attach( mBuffer->GetData(), bm_width, bm_height, bm_width * 3 );
00372     }
00373     else
00374         mRenderingBuffer.attach( mBuffer->GetData(), width, height, width * 3 );
00375 
00376     mRendererBase.reset_clipping( true );
00377     mTransform.reset();
00378     mTransform.premultiply( agg::trans_affine_translation( 0.0, height ) );
00379     mTransform.premultiply( agg::trans_affine_scaling( 1.0 / scalex, -1.0 / scaley ) );
00380     mStrokeWidth = ( scalex + scaley ) / 2.0;
00381 }
00382 
00383 
00384 //--------------------------------------------------------------------------
00385 //  void wxPLDevAGG::SetWidth( PLStream *pls )
00386 //
00387 //  Set the width of the drawing pen.
00388 //--------------------------------------------------------------------------
00389 void wxPLDevAGG::SetWidth( PLStream *pls )
00390 {
00391     mStrokeWidth = ( scalex + scaley ) / 2.0 * ( pls->width > 0 ? pls->width : 1 ); // TODO: why and when ist width 0???
00392 }
00393 
00394 
00395 //--------------------------------------------------------------------------
00396 //  void wxPLDevAGG::SetColor0( PLStream *pls )
00397 //
00398 //  Set color from colormap 0.
00399 //--------------------------------------------------------------------------
00400 void wxPLDevAGG::SetColor0( PLStream *pls )
00401 {
00402     mColorRedStroke   = pls->cmap0[pls->icol0].r;
00403     mColorGreenStroke = pls->cmap0[pls->icol0].g;
00404     mColorBlueStroke  = pls->cmap0[pls->icol0].b;
00405     mStrokeOpacity    = (wxUint8) ( pls->cmap0[pls->icol0].a * 255 );
00406 }
00407 
00408 
00409 //--------------------------------------------------------------------------
00410 //  void wxPLDevAGG::SetColor1( PLStream *pls )
00411 //
00412 //  Set color from colormap 1.
00413 //--------------------------------------------------------------------------
00414 void wxPLDevAGG::SetColor1( PLStream *pls )
00415 {
00416     mColorRedStroke   = pls->curcolor.r;
00417     mColorGreenStroke = pls->curcolor.g;
00418     mColorBlueStroke  = pls->curcolor.b;
00419     mStrokeOpacity    = (wxUint8) ( pls->curcolor.a * 255 );
00420 }
00421 
00422 
00423 //--------------------------------------------------------------------------
00424 //  void wxPLDevAGG::SetExternalBuffer( void* dc )
00425 //
00426 //  Adds a dc to the device. In that case, the drivers doesn't provide
00427 //  a GUI. A new buffer (image) will be created and set up.
00428 //--------------------------------------------------------------------------
00429 void wxPLDevAGG::SetExternalBuffer( void* image )
00430 {
00431     mBuffer = (wxImage *) image; // Add the image to the device
00432     mRenderingBuffer.attach( mBuffer->GetData(), width, height, width * 3 );
00433 
00434     mRendererBase.reset_clipping( true );
00435     mTransform.reset();
00436     mTransform.premultiply( agg::trans_affine_translation( 0.0, height ) );
00437     mTransform.premultiply( agg::trans_affine_scaling( 1.0 / scalex, -1.0 / scaley ) );
00438     mStrokeWidth = ( scalex + scaley ) / 2.0;
00439 
00440     ready  = true;
00441     ownGUI = false;
00442 }
00443 
00444 
00445 #ifdef HAVE_FREETYPE
00446 
00447 //--------------------------------------------------------------------------
00448 //  void wxPLDevAGG::PutPixel( short x, short y, PLINT color )
00449 //
00450 //  Draw a pixel in color color @ (x,y).
00451 //--------------------------------------------------------------------------
00452 void wxPLDevAGG::PutPixel( short x, short y, PLINT color )
00453 {
00454     mBuffer->SetRGB( x, y, GetRValue( color ), GetGValue( color ), GetBValue( color ) );
00455     AddtoClipRegion( x, y, x, y );
00456 }
00457 
00458 
00459 //--------------------------------------------------------------------------
00460 //  void wxPLDevAGG::PutPixel( short x, short y )
00461 //
00462 //  Draw a pixel in current color @ (x,y).
00463 //--------------------------------------------------------------------------
00464 void wxPLDevAGG::PutPixel( short x, short y )
00465 {
00466     mBuffer->SetRGB( x, y, mColorRedStroke, mColorGreenStroke, mColorBlueStroke );
00467     AddtoClipRegion( x, y, x, y );
00468 }
00469 
00470 
00471 //--------------------------------------------------------------------------
00472 //  PLINT wxPLDevAGG::GetPixel( short x, short y )
00473 //
00474 //  Get color information from pixel @ (x,y).
00475 //--------------------------------------------------------------------------
00476 PLINT wxPLDevAGG::GetPixel( short x, short y )
00477 {
00478     return RGB( mBuffer->GetRed( x, y ), mBuffer->GetGreen( x, y ), mBuffer->GetBlue( x, y ) );
00479 }
00480 
00481 #endif // HAVE_FREETYPE
00482 
00483 
00484 void wxPLDevAGG::PSDrawTextToDC( char* utf8_string, bool drawText )
00485 {
00486     // Log_Verbose( "%s", __FUNCTION__ );
00487     printf( "utf8_string=%s\n", utf8_string );
00488 
00489     double start_x = 0.0;
00490     double start_y = 0.0;
00491 
00492     //wchar_t str[512];
00493     //size_t len=wxConvUTF8.ToWChar( str, 512, utf8_string );
00494     size_t len   = strlen( utf8_string );
00495     char   * str = utf8_string;
00496     printf( "len=%d\n", len );
00497 
00498     const agg::glyph_cache* glyph;
00499     if ( !drawText )
00500     {
00501         double x         = 0;
00502         double y         = 0;
00503         bool   first     = true;
00504         char   * saveStr = str;
00505         while ( *str && len )
00506         {
00507             glyph = mFontManager.glyph( *str );
00508             if ( glyph )
00509             {
00510                 if ( !first )
00511                     mFontManager.add_kerning( &x, &y );
00512                 x    += glyph->advance_x;
00513                 y    += glyph->advance_y;
00514                 first = false;
00515             }
00516             textHeight = textHeight > ( glyph->bounds.y2 - glyph->bounds.y1 + yOffset ) ?
00517                          textHeight : ( glyph->bounds.y2 - glyph->bounds.y1 + yOffset );
00518             ++str; --len;
00519         }
00520         textWidth = x;
00521         printf( "str: %s, textWidth=%lf\n", saveStr, textWidth );
00522     }
00523     else
00524     {
00525         for ( size_t i = 0; i < len && str[i]; i++ )
00526         {
00527             glyph = mFontManager.glyph( str[i] );
00528             if ( glyph )
00529             {
00530                 printf( "before: start_x=%f, start_y=%f\n", start_x, start_y );
00531                 if ( i )
00532                     mFontManager.add_kerning( &start_x, &start_y );
00533                 printf( "after: start_x=%f, start_y=%f\n", start_x, start_y );
00534                 mFontManager.init_embedded_adaptors( glyph, start_x, start_y );
00535 
00536                 mRendererSolid.color( agg::rgba8( mColorRedStroke, mColorGreenStroke, mColorBlueStroke, mStrokeOpacity ) );
00537                 agg::render_scanlines( mFontManager.gray8_adaptor(), mFontManager.gray8_scanline(), mRendererSolid );
00538 
00539                 start_x += glyph->advance_x / scalex;
00540                 //start_y += glyph->advance_y/scaley;
00541             }
00542         }
00543     }
00544 
00545     memset( utf8_string, '\0', max_string_length );
00546 }
00547 
00548 
00549 void wxPLDevAGG::PSSetFont( PLUNICODE fci )
00550 {
00551     // convert the fci to Base14/Type1 font information
00552     wxString fontname = fontdir + wxString( plP_FCI2FontName( fci, TrueTypeLookup, N_TrueTypeLookup ), *wxConvCurrent );
00553 
00554     if ( !mFontEngine.load_font( "/usr/share/fonts/truetype/freefont/FreeSans.ttf", 0, agg::glyph_ren_agg_gray8 ) )
00555         plabort( "Font could not be loaded" );
00556     //mFontEngine.load_font( "c:\\windows\\fonts\\arial.ttf", 0, agg::glyph_ren_agg_gray8 );
00557     mFontEngine.height( fontSize * fontScale );
00558     mFontEngine.width( fontSize * fontScale );
00559     mFontEngine.hinting( true );
00560     mFontEngine.flip_y( false );
00561     mContour.width( fontSize * fontScale * 0.2 );
00562 }
00563 
00564 
00565 void wxPLDevAGG::ProcessString( PLStream* pls, EscText* args )
00566 {
00567     plabort( "The AGG backend can't process the text yet own its own!" );
00568 
00569     // Check that we got unicode, warning message and return if not
00570     if ( args->unicode_array_len == 0 )
00571     {
00572         printf( "Non unicode string passed to a wxWidgets driver, ignoring\n" );
00573         return;
00574     }
00575 
00576     // Check that unicode string isn't longer then the max we allow
00577     if ( args->unicode_array_len >= 500 )
00578     {
00579         printf( "Sorry, the wxWidgets drivers only handles strings of length < %d\n", 500 );
00580         return;
00581     }
00582 
00583     // Calculate the font size (in pixels)
00584     fontSize = pls->chrht * DEVICE_PIXELS_PER_MM * 1.2 * scaley;
00585 
00586     // calculate rotation of text
00587     plRotationShear( args->xform, &rotation, &shear, &stride );
00588     rotation -= pls->diorot * M_PI / 2.0;
00589     cos_shear = cos( shear );
00590     sin_shear = sin( shear );
00591 
00592     PSDrawText( args->unicode_array, args->unicode_array_len, false );
00593     printf( "textWidth=%f, textHeight=%f\n", textWidth, textHeight );
00594 
00595     agg::trans_affine mtx;
00596     mtx.reset();
00597     mtx *= agg::trans_affine_translation( args->x, args->y );
00598     //mtx *= agg::trans_affine_rotation( rotation );
00599     //mtx *= agg::trans_affine_skewing( shear, shear );
00600     mtx *= mTransform;
00601     mtx *= agg::trans_affine_translation( -args->just * textWidth / scalex, -0.5 * textHeight );
00602     mtx *= agg::trans_affine_translation( -args->just * textWidth / scalex, -0.5 * textHeight );
00603     mFontEngine.transform( mtx );
00604 
00605     PSDrawText( args->unicode_array, args->unicode_array_len, true );
00606 
00607     AddtoClipRegion( 0, 0, width, height );
00608 }

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