48 #include <wx/ustring.h>
55 #if defined ( WXPLVIEWER_DEBUG ) || defined ( PLPLOT_WX_DEBUG_OUTPUT )
85 typedef std::pair< PLUNICODE *, PLUNICODE *> uniIterPair;
88 std::vector< uniIterPair > lines( 1, uniIterPair( args->
unicode_array, textEnd ) );
93 lines.back().second = uni;
94 lines.push_back( uniIterPair( uni + 1, textEnd ) );
101 printf(
"Non unicode string passed to the wxWidgets driver, ignoring\n" );
108 printf(
"Sorry, the wxWidgets drivers only handles strings of length < %d\n", 500 );
119 bool currentUnderlined =
false;
123 std::vector<wxCoord> lineWidths( lines.size() );
124 std::vector<wxCoord> lineHeights( lines.size() );
125 std::vector<wxCoord> lineDepths( lines.size() );
130 wxCoord paraWidth = 0;
131 wxCoord paraHeight = 0;
133 bool testUnderlined = currentUnderlined =
false;
134 PLFLT identityMatrix[6];
136 for (
size_t i = 0; i < lines.size(); ++i )
138 DrawTextLine( lines[i].first, lines[i].second - lines[i].first, 0, 0, 0, 0, identityMatrix, baseFontSize,
false,
139 testUnderlined, testFci,
140 0, 0, 0, 0.0, lineWidths[i], lineHeights[i], lineDepths[i] );
141 paraWidth =
MAX( paraWidth, lineWidths[i] );
142 paraHeight += lineHeights[i] + lineDepths[i];
151 wxCoord cumSumHeight = 0;
154 PLFLT textTransform[6];
156 textTransform[0] = args->
xform[0];
157 textTransform[2] = args->
xform[1];
158 textTransform[1] = args->
xform[2];
159 textTransform[3] = args->
xform[3];
160 textTransform[4] = 0.0;
161 textTransform[5] = 0.0;
162 PLFLT diorotTransform[6];
165 diorotTransform[0] = 1;
166 diorotTransform[1] = 0;
167 diorotTransform[2] = 0;
168 diorotTransform[3] = 1;
170 else if ( diorot == 1.0 )
172 diorotTransform[0] = 0;
173 diorotTransform[1] = -1;
174 diorotTransform[2] = 1;
175 diorotTransform[3] = 0;
177 else if ( diorot == 2.0 )
179 diorotTransform[0] = -1;
180 diorotTransform[1] = 0;
181 diorotTransform[2] = 0;
182 diorotTransform[3] = -1;
184 else if ( diorot == 3.0 )
186 diorotTransform[0] = 0;
187 diorotTransform[1] = 1;
188 diorotTransform[2] = -1;
189 diorotTransform[3] = 0;
194 PLFLT cosAngle = cos( angle );
195 PLFLT sinAngle = sin( angle );
196 diorotTransform[0] = cosAngle;
197 diorotTransform[1] = -sinAngle;
198 diorotTransform[2] = sinAngle;
199 diorotTransform[3] = cosAngle;
201 diorotTransform[4] = 0;
202 diorotTransform[5] = 0;
204 PLFLT finalTransform[6];
205 memcpy( finalTransform, textTransform,
sizeof (
PLFLT ) * 6 );
208 std::vector<wxCoord> lineWidths_ignored( lines.size() );
209 std::vector<wxCoord> lineHeights_ignored( lines.size() );
210 std::vector<wxCoord> lineDepths_ignored( lines.size() );
211 for (
size_t i = 0; i < lines.size(); ++i )
213 DrawTextLine( lines[i].first, lines[i].second - lines[i].first,
216 -lineWidths[i] * args->
just, 0.5 * ( lineHeights[i] ) - cumSumHeight,
217 finalTransform, baseFontSize,
true,
220 lineHeights_ignored[i], lineDepths_ignored[i] );
226 cumSumHeight += lineHeights[i] + lineDepths[i];
242 void PlDevice::DrawTextLine(
PLUNICODE* ucs4,
int ucs4Len, wxCoord xOrigin, wxCoord yOrigin, wxCoord x, wxCoord y,
PLFLT *transform,
PLFLT baseFontSize,
bool drawText,
bool &underlined,
PLUNICODE &fci,
unsigned char red,
unsigned char green,
unsigned char blue,
PLFLT alpha, wxCoord &textWidth, wxCoord &textHeight, wxCoord &textDepth )
247 PLFLT scaledFontSize = baseFontSize;
251 PLFLT scaledOffset = 0.;
263 PLFLT empiricalSymmetricFactor = 1.2;
265 wxCoord sectionWidth;
266 wxCoord sectionHeight;
267 wxCoord sectionDepth;
286 PLFLT sectionTransform[6];
287 memcpy( sectionTransform, transform,
sizeof ( sectionTransform ) );
299 while ( i < ucs4Len )
308 section += wxUString( (wxChar32) ucs4[i] );
313 DrawTextSection( section, xOrigin, yOrigin, x + textWidth, y + scaledOffset, transform,
314 scaledFontSize,
drawText, underlined, fci, red, green, blue, alpha, yScale, sectionWidth, sectionHeight, sectionDepth );
315 textWidth += sectionWidth;
316 textHeight =
MAX( textHeight, sectionHeight + scaledOffset );
317 textDepth =
MAX( textDepth, sectionDepth - scaledOffset );
318 section = wxEmptyString;
333 scaledFontSize = baseFontSize * Scale;
334 scaledOffset = yScale * Offset * baseFontSize * ( level > 0 ? 1.0 / empiricalSymmetricFactor : -1.0 * empiricalSymmetricFactor );
348 scaledFontSize = baseFontSize * Scale;
349 scaledOffset = yScale * Offset * baseFontSize * ( level > 0 ? 1.0 / empiricalSymmetricFactor : -1.0 * empiricalSymmetricFactor );
352 underlined = !underlined;
362 DrawTextSection( section, xOrigin, yOrigin, x + textWidth, y + scaledOffset, transform,
363 scaledFontSize,
drawText, underlined, fci, red, green, blue, alpha, yScale, sectionWidth, sectionHeight, sectionDepth );
364 textWidth += sectionWidth;
365 textHeight =
MAX( textHeight, sectionHeight + scaledOffset );
366 textDepth =
MAX( textDepth, sectionDepth - scaledOffset );
367 section = wxEmptyString;
375 section += wxUString( (wxChar32) ucs4[i] );
382 DrawTextSection( section, xOrigin, yOrigin, x + textWidth, y + scaledOffset, transform,
383 scaledFontSize,
drawText, underlined, fci, red, green, blue, alpha, yScale, sectionWidth, sectionHeight, sectionDepth );
384 textWidth += sectionWidth;
385 textHeight =
MAX( textHeight, sectionHeight + scaledOffset );
386 textDepth =
MAX( textDepth, sectionDepth - scaledOffset );
411 Scaler( wxDC * dc,
double xScale,
double yScale )
417 dc->SetUserScale( xScale, yScale );
448 dc->SetLogicalOrigin( xOrigin, yOrigin );
478 m_pen = dc->GetPen();
481 dc->SetBrush( brush );
546 TextObjectsChanger( wxDC *dc,
const wxFont &font,
const wxColour &textForeground,
const wxColour &textBackground )
551 dc->SetTextForeground( textForeground );
552 dc->SetTextBackground( textBackground );
568 dc->SetTextForeground( textForeground );
569 dc->SetTextBackground( textBackground );
601 wxRect newRect = rect;
605 dc->SetClippingRegion( wxRect( -1, -1, 1, 1 ) );
607 dc->SetClippingRegion( rect );
614 m_dc->DestroyClippingRegion();
615 m_dc->SetClippingRegion( wxRect( 0, 0, 0, 0 ) );
616 m_dc->DestroyClippingRegion();
649 std::fstream fin(
"/dev/urandom", std::ios::in );
655 fin.open(
"/dev/random", std::ios::in );
670 unsigned int next =
m_seed;
675 result = (
unsigned int) ( next /
max ) % 2048;
680 result ^= (
unsigned int) ( next /
max ) % 1024;
685 result ^= (
unsigned int) ( next /
max ) % 1024;
691 static const unsigned int max = 65536;
698 unsigned char plFontFamily, plFontStyle, plFontWeight;
713 m_size = std::numeric_limits<PLFLT>::quiet_NaN();
724 if ( createFontOnConstruction )
736 m_font = wxFont(
pt, family, style, weight,
m_underlined, wxEmptyString, wxFONTENCODING_DEFAULT );
741 if (
pt == wxDEFAULT )
777 Font newFont( fci, scaledFontSize, underlined );
796 : m_plplotEdgeLength(
PLFLT( SHRT_MAX ) ), m_interactiveTextImage( 1, 1 )
814 throw(
"wxPLDevice::wxPLDevice: unknown failure in new wxGCDC( gc )" );
819 strcpy(
m_mfo, mfo );
823 #ifdef WXPLVIEWER_DEBUG
824 strcpy(
m_mfo,
"plplotMemoryMap" );
826 strcpy(
m_mfo,
"plplotMemoryMap??????????" );
904 #ifdef PL_WXWIDGETS_IPC3
905 m_header.completeFlag = 1;
958 for (
PLINT i = 1; i < npts; i++ )
975 x1 = x1 < 0 ? 0 : x1;
977 y1 = y1 < 0 ? 0 : y1;
985 if ( width > 0 && height > 0 )
990 wxColour bgColour( r, g, b, a * 255 );
993 m_dc->DrawRectangle( x, y, width, height );
1016 wxCoord xoffset = 0;
1017 wxCoord yoffset = 0;
1027 m_dc->DrawPolygon(
pls->
dev_npts, points, xoffset, yoffset, wxODDEVEN_RULE );
1031 m_dc->DrawPolygon(
pls->
dev_npts, points, xoffset, yoffset, wxWINDING_RULE );
1072 m_dc->SetLogicalFunction( on ? wxXOR : wxCOPY );
1084 throw(
"wxPLDevice::SetDC The DC must be set before initialisation. The device is outputting to a separate viewer" );
1090 #if wxVERSION_NUMBER >= 2902
1098 wxGCDC *gcdc = NULL;
1103 gcdc = dynamic_cast< wxGCDC* >(
m_dc );
1107 throw(
"unknown failure in dynamic_cast< wxGCDC* >( m_dc )" );
1110 m_gc = gcdc->GetGraphicsContext();
1112 strcpy(
m_mfo,
"" );
1140 void wxPLDevice::DrawTextSection( wxString section, wxCoord xOrigin, wxCoord yOrigin, wxCoord x, wxCoord y,
PLFLT *transform,
PLFLT scaledFontSize,
bool drawText,
bool underlined,
PLUNICODE fci,
unsigned char red,
unsigned char green,
unsigned char blue,
PLFLT alpha,
PLFLT &yScale, wxCoord §ionWidth, wxCoord §ionHeight, wxCoord §ionDepth )
1161 PLFLT empiricalYOffset = -0.020 * scaledFontSize *
m_yScale;
1162 wxCoord empiricalY = y + empiricalYOffset;
1177 m_dc->GetTextExtent( section, §ionWidth, §ionHeight,
1178 §ionDepth, &leading, &theFont );
1185 §ionDepth, &leading, &theFont );
1196 sectionHeight -= leading;
1197 sectionDepth += leading;
1206 m_dc->SetTextBackground( wxColour( red, green, blue, alpha * 255 ) );
1207 m_dc->SetTextForeground( wxColour( red, green, blue, alpha * 255 ) );
1210 PLINT rcx[4], rcy[4];
1213 for (
int i = 0; i < 4; i++ )
1218 Clipper clipper(
m_dc, wxRegion( 4, cpoints ).GetBox() );
1225 #if wxVERSION_NUMBER >= 2902
1226 wxAffineMatrix2D originalDcMatrix =
m_dc->GetTransformMatrix();
1228 wxAffineMatrix2D newMatrix = originalDcMatrix;
1230 wxAffineMatrix2D textMatrix;
1237 transform[0], transform[2],
1238 transform[1], transform[3] ),
1240 xTransform, yTransform ) );
1241 newMatrix.Concat( textMatrix );
1242 m_dc->SetTransformMatrix( newMatrix );
1246 m_dc->SetTransformMatrix( originalDcMatrix );
1251 wxGraphicsMatrix originalGcMatrix =
m_gc->GetTransform();
1283 wxGraphicsMatrix matrix =
m_gc->CreateMatrix(
1284 transform[0], -transform[1],
1285 -transform[2], transform[3],
1286 xTransform, -yTransform );
1287 wxGraphicsMatrix reflectMatrix =
m_gc->CreateMatrix();
1288 m_gc->ConcatTransform( matrix );
1290 m_gc->SetTransform( originalGcMatrix );
1304 PLFLT angle = atan2( transform[1], transform[0] ) * 180.0 /
M_PI;
1360 plP_gphy( &xmin, &xmax, &ymin, &ymax );
1420 #ifdef PL_WXWIDGETS_IPC3
1434 #ifdef PL_WXWIDGETS_IPC3
1441 m_header.transmissionType = transmissionType;
1446 switch ( transmissionType )
1450 m_header.locateModeFlag = 1;
1456 m_header.plbufAmountToTransmit = 0;
1463 case transmissionFlush:
1468 throw(
"wxPLDevice::TransmitBuffer: called with invalid value of transmissionType" );
1472 #ifdef PLPLOT_WX_DEBUG_OUTPUT
1473 std::cerr <<
"Before transmitBytes" << std::endl;
1474 std::cerr <<
"transmissionType = " << static_cast<unsigned int>( m_header.transmissionType ) << std::endl;
1475 std::cerr <<
"plbufAmountToTransmit = " << m_header.plbufAmountToTransmit << std::endl;
1476 std::cerr <<
"viewerOpenFlag = " << m_header.viewerOpenFlag << std::endl;
1477 std::cerr <<
"locateModeFlag = " << m_header.locateModeFlag << std::endl;
1478 std::cerr <<
"completeFlag = " << m_header.completeFlag << std::endl;
1479 #endif // #ifdef PLPLOT_WX_DEBUG_OUTPUT
1481 if ( m_header.plbufAmountToTransmit > 0 )
1491 catch (
const char *message )
1494 plwarn(
"wxPLDevice::TransmitBuffer: error" );
1499 plwarn(
"wxPLDevice::TransmitBuffer: Unknown error" );
1502 #else // #ifdef PL_WXWIDGETS_IPC3
1505 const size_t headerSize =
sizeof ( transmissionType ) +
sizeof (
size_t );
1508 const size_t counterLimit = 10000;
1509 bool completed =
false;
1510 while ( !completed && counter < counterLimit )
1519 size_t copyAmount = 0;
1520 size_t freeSpace = 0;
1538 if ( freeSpace <= headerSize )
1551 plwarn(
"wxWidgets wrapping buffer" );
1565 if ( amountToCopy == 0 )
1574 && amountToCopy == 0 )
1577 (
void *) ( &transmissionType ),
sizeof ( transmissionType ) );
1613 (
void *) ( &transmissionType ),
sizeof ( transmissionType ) );
1627 if ( freeSpace > headerSize )
1630 copyAmount =
MIN( amountToCopy, freeSpace - headerSize );
1633 if ( copyAmount != amountToCopy )
1642 (
char *) ( ©Amount ),
sizeof ( copyAmount ) );
1649 amountToCopy -= copyAmount;
1675 if ( counter == counterLimit )
1680 #endif // #ifdef PL_WXWIDGETS_IPC3
1686 if ( strlen(
m_mfo ) > 0 )
1688 #ifdef PL_WXWIDGETS_IPC3
1689 const size_t mapSize =
sizeof ( shmbuf );
1691 const size_t mapSize = 1024 * 1024;
1697 static Rand randomGenerator;
1698 while ( nTries < 10 )
1701 for (
int i = 0; i < strlen(
m_mfo ); ++i )
1703 if (
m_mfo[i] ==
'?' )
1704 mapName[i] =
'A' + (char) ( randomGenerator() % 26 );
1706 mapName[i] =
m_mfo[i];
1709 mapName[strlen(
m_mfo )] =
'\0';
1713 pldebug(
"wxPLDevice::SetupMemoryMap",
"nTries = %d, mapName = %s\n", nTries, mapName );
1719 #ifndef PL_WXWIDGETS_IPC3
1720 strcpy( mutexName, mapName );
1721 strcat( mutexName,
"mut" );
1722 pldebug(
"wxPLDevice::SetupMemoryMap",
"nTries = %d, mutexName = %s\n", nTries, mutexName );
1726 #endif // #ifndef PL_WXWIDGETS_IPC3
1736 plwarn(
"Error creating memory map for wxWidget instruction transmission. The plots will not be displayed" );
1740 #ifdef PL_WXWIDGETS_IPC3
1744 m_header.viewerOpenFlag = 0;
1745 m_header.locateModeFlag = 0;
1746 m_header.completeFlag = 0;
1747 #else // #ifdef PL_WXWIDGETS_IPC3
1751 header->viewerOpenFlag = 0;
1752 header->locateModeFlag = 0;
1753 header->completeFlag = 0;
1754 #endif // #ifdef PL_WXWIDGETS_IPC3
1763 wxArrayString files;
1764 wxString utilsDir = wxString( wxT(
BUILD_DIR ) ) + wxString( wxT(
"/utils" ) );
1765 wxDir::GetAllFiles( utilsDir, &files, exeName, wxDIR_FILES | wxDIR_DIRS );
1766 if ( files.size() == 0 )
1767 wxDir::GetAllFiles( utilsDir, &files, exeName + wxT(
".exe" ), wxDIR_FILES | wxDIR_DIRS );
1768 if ( files.size() > 0 )
1774 wxArrayString files;
1775 wxDir::GetAllFiles( wxT(
BIN_DIR ), &files, exeName, wxDIR_FILES | wxDIR_DIRS );
1776 if ( files.size() == 0 )
1777 wxDir::GetAllFiles( wxT(
BIN_DIR ), &files, exeName + wxT(
".exe" ), wxDIR_FILES | wxDIR_DIRS );
1778 if ( files.size() > 0 )
1783 command << wxT(
"\"" ) << exeName << wxT(
"\" " ) << wxString( mapName, wxConvUTF8 ) << wxT(
" " ) <<
1785 #ifndef WXPLVIEWER_DEBUG
1788 if ( wxExecute(
command, wxEXEC_ASYNC ) == 0 )
1795 #else // ifndef WXPLVIEWER_DEBUG
1796 wxString runMessage;
1797 runMessage <<
"Begin Running " NAME_wxPLViewer " in the debugger now to continue. Use the parameters: plplotMemoryMap " <<
1802 std::cerr << runMessage << std::endl;
1803 #endif // ifndef WXPLVIEWER_DEBUG
1805 #ifdef PL_WXWIDGETS_IPC3
1822 #ifdef PLPLOT_WX_DEBUG_OUTPUT
1823 std::cerr <<
"After receiveBytes" << std::endl;
1824 std::cerr <<
"transmissionType = " << static_cast<unsigned int>( m_header.transmissionType ) << std::endl;
1825 std::cerr <<
"plbufAmountToTransmit = " << m_header.plbufAmountToTransmit << std::endl;
1826 std::cerr <<
"viewerOpenFlag = " << m_header.viewerOpenFlag << std::endl;
1827 std::cerr <<
"locateModeFlag = " << m_header.locateModeFlag << std::endl;
1828 std::cerr <<
"completeFlag = " << m_header.completeFlag << std::endl;
1829 #endif // #ifdef PLPLOT_WX_DEBUG_OUTPUT
1831 catch (
const char *message )
1834 plwarn(
"wxPLDevice::SetupMemoryMap: error" );
1838 plwarn(
"wxPLDevice::SetupMemoryMap: Unknown error" );
1841 size_t &viewerSignal = m_header.viewerOpenFlag;
1842 #else // #ifdef PL_WXWIDGETS_IPC3
1844 #ifndef WXPLVIEWER_DEBUG
1845 size_t maxTries = 1000;
1846 #else // ifndef WXPLVIEWER_DEBUG
1847 size_t maxTries = 100000;
1848 #endif // ifndef WXPLVIEWER_DEBUG
1851 size_t &viewerSignal =
header->viewerOpenFlag;
1852 while ( counter < maxTries && viewerSignal == 0 )
1857 #endif // #ifdef PL_WXWIDGETS_IPC3
1858 if ( viewerSignal == 0 )
1868 #ifdef PL_WXWIDGETS_IPC3
1871 *graphicsIn = m_header.graphicsIn;
1872 #else // #ifdef PL_WXWIDGETS_IPC3
1875 bool gotResponse =
false;
1876 while ( !gotResponse )
1878 wxMilliSleep( 100 );
1880 gotResponse =
header->locateModeFlag == 0;
1884 *graphicsIn =
header->graphicsIn;
1885 #endif //ifdef PL_WXWIDGETS_IPC3
1889 plwarn(
"plGetCursor cannot be used when the user supplies a wxDC or until " NAME_wxPLViewer " is initialised" );
1890 graphicsIn->
dX = -1;
1891 graphicsIn->
dY = -1;
1892 graphicsIn->
pX = -1;
1893 graphicsIn->
pY = -1;
1904 PLINT rcx[4], rcy[4];
1908 for (
int i = 0; i < 4; i++ )
1913 return wxRegion( 4, cpoints );